973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
b311480e |
13 | |
7fd59977 |
14 | |
7fd59977 |
15 | #include <MoniTool_DataMapIteratorOfDataMapOfTimer.hxx> |
42cf5bc1 |
16 | #include <MoniTool_DataMapOfTimer.hxx> |
17 | #include <MoniTool_Timer.hxx> |
7fd59977 |
18 | #include <MoniTool_TimerSentry.hxx> |
42cf5bc1 |
19 | #include <OSD_Timer.hxx> |
20 | #include <Standard_Type.hxx> |
7fd59977 |
21 | |
42cf5bc1 |
22 | #include <stdio.h> |
25e59720 |
23 | IMPLEMENT_STANDARD_RTTIEXT(MoniTool_Timer,Standard_Transient) |
92efcf78 |
24 | |
7fd59977 |
25 | //======================================================================= |
26 | //function : Dump |
27 | //purpose : |
28 | //======================================================================= |
7fd59977 |
29 | void MoniTool_Timer::Dump(Standard_OStream &ostr) |
30 | { |
31 | Standard_Integer hours, minutes; |
32 | Standard_Real seconds, CPUtime, user, system; |
33 | |
34 | myTimer.Show(seconds,minutes,hours,CPUtime); |
35 | myTimer.OSD_Chronometer::Show(user,system); |
36 | |
37 | Standard_Real elapsed = seconds + minutes*60 + hours*3600; |
38 | |
39 | char buff[1024]; |
91322f44 |
40 | Sprintf ( buff, "Elapsed:%6.1f sec, CPU User:%9.4f sec, CPU Sys:%9.4f sec, hits: %d", |
7fd59977 |
41 | elapsed, user, system, myCount ); |
42 | |
43 | ostr << buff << endl; |
44 | } |
45 | |
46 | //======================================================================= |
47 | //function : Dictionary |
48 | //purpose : Return DataMapOfTimer |
49 | //======================================================================= |
50 | |
51 | MoniTool_DataMapOfTimer& MoniTool_Timer::Dictionary () |
52 | { |
53 | static MoniTool_DataMapOfTimer dic; |
54 | return dic; |
55 | } |
56 | |
57 | //======================================================================= |
58 | //function : Timer |
59 | //purpose : Return handle for timer from map |
60 | //======================================================================= |
61 | |
62 | Handle(MoniTool_Timer) MoniTool_Timer::Timer(const Standard_CString name) |
63 | { |
64 | // AmendAccess(); |
65 | MoniTool_DataMapOfTimer &dic = Dictionary(); |
66 | if ( dic.IsBound(name) ) |
67 | return dic.Find(name); |
68 | Handle(MoniTool_Timer) MT = new MoniTool_Timer; |
69 | MT->Timer().Reset(); |
70 | dic.Bind(name,MT); |
71 | return MT; |
72 | } |
73 | |
74 | //======================================================================= |
75 | //function : ClearTimers |
76 | //purpose : Clears all the map of timers |
77 | //======================================================================= |
78 | |
79 | void MoniTool_Timer::ClearTimers() |
80 | { |
81 | Dictionary().Clear(); |
82 | } |
83 | |
84 | //======================================================================= |
85 | //function : DumpTimers |
86 | //purpose : Shows all timer from Dictionary |
87 | //======================================================================= |
88 | |
89 | void MoniTool_Timer::DumpTimers (Standard_OStream &ostr) |
90 | { |
91 | MoniTool_DataMapOfTimer &dic = Dictionary(); |
92 | MoniTool_DataMapIteratorOfDataMapOfTimer iter(dic); |
93 | |
94 | Standard_Integer NbTimers = dic.Extent(); |
95 | |
96 | ostr << "DUMP OF TIMERS:" << endl; |
97 | Standard_CString *keys = new Standard_CString[NbTimers]; |
98 | Standard_Integer i=0; |
99 | for( ; iter.More() && i < NbTimers; iter.Next()) { |
100 | keys[i++] = iter.Key(); |
101 | } |
102 | for(i=0; i < NbTimers; i++) { |
103 | Standard_Integer ntmp = 0; |
104 | Standard_CString stmp = 0; |
105 | for(Standard_Integer j=0; j < NbTimers; j++) { |
106 | if ( keys[j] && ( ! stmp || strcmp(stmp,keys[j]) > 0 ) ) { |
107 | ntmp=j; |
108 | stmp=keys[j]; |
109 | } |
110 | } |
111 | //Handle(MoniTool_Timer) MT = iter.Value(); |
112 | char buff[1024]; |
91322f44 |
113 | Sprintf ( buff, "%-20s\t", stmp ); |
7fd59977 |
114 | ostr << "TIMER: " << buff; |
115 | //iter.Value()->Dump ( ostr ); |
116 | Timer(stmp)->Dump(ostr); |
117 | keys[ntmp]=0; |
118 | if ( Timer(stmp)->IsRunning() ) cerr << "Warning: timer " << stmp << " is running" << endl; |
119 | } |
120 | delete[] keys; |
121 | } |
122 | |
123 | //======================================================================= |
124 | //function : ComputeAmendments |
125 | //purpose : |
126 | //======================================================================= |
127 | |
128 | static Standard_Real amAccess=0., amInternal=0., amExternal=0., amError=0.; |
129 | |
130 | void MoniTool_Timer::ComputeAmendments () |
131 | { |
132 | const Standard_Integer NBTESTS = 100000; |
133 | |
134 | Standard_Integer i; |
135 | |
136 | Handle(MoniTool_Timer) MT0 = MoniTool_Timer::Timer("_mt_amend_0_"); |
137 | Handle(MoniTool_Timer) MT1 = MoniTool_Timer::Timer("_mt_amend_1_"); |
138 | Handle(MoniTool_Timer) MT2 = MoniTool_Timer::Timer("_mt_amend_2_"); |
139 | Handle(MoniTool_Timer) MT3 = MoniTool_Timer::Timer("_mt_amend_3_"); |
140 | MT0->Reset(); |
141 | MT1->Reset(); |
142 | MT2->Reset(); |
143 | MT3->Reset(); |
144 | MoniTool_Timer::Timer("_mt_amend_t1_")->Reset(); |
145 | MoniTool_Timer::Timer("_mt_amend_t2_")->Reset(); |
146 | MoniTool_Timer::Timer("_mt_amend_t3_")->Reset(); |
147 | |
148 | // reference test |
149 | MT0->Start(); |
150 | for ( i=1; i <= NBTESTS; i++ ) { |
151 | for ( int k=1; k <= 100; k++ ) Sqrt ( i+k ); |
152 | } |
153 | MT0->Stop(); |
154 | |
155 | // test for direct access |
156 | Handle(MoniTool_Timer) MT = MoniTool_Timer::Timer("_mt_amend_t1_"); |
157 | MT1->Start(); |
158 | for ( i=1; i <= NBTESTS; i++ ) { |
159 | MT->Start(); |
160 | for ( int k=1; k <= 100; k++ ) Sqrt ( i+k ); |
161 | MT->Stop(); |
162 | } |
163 | MT1->Stop(); |
164 | |
165 | // test for using Sentry |
166 | MT2->Start(); |
167 | for ( i=1; i <= NBTESTS; i++ ) { |
168 | MoniTool_TimerSentry TS ("_mt_amend_t2_"); |
169 | for ( int k=1; k <= 100; k++ ) Sqrt ( i+k ); |
170 | } |
171 | MT2->Stop(); |
172 | |
173 | // test for access by name |
174 | MT3->Start(); |
175 | for ( i=1; i <= NBTESTS; i++ ) { |
176 | MoniTool_Timer::Start("_mt_amend_t3_"); |
177 | for ( int k=1; k <= 100; k++ ) Sqrt ( i+k ); |
178 | MoniTool_Timer::Stop("_mt_amend_t3_"); |
179 | } |
180 | MT3->Stop(); |
181 | |
182 | // analyze results |
183 | Standard_Real cpu0, cpu1, cpu2, cpu3, cput1, cput2, cput3; |
184 | cpu0 = MoniTool_Timer::Timer("_mt_amend_0_")->CPU(); |
185 | cpu1 = MoniTool_Timer::Timer("_mt_amend_1_")->CPU(); |
186 | cput1 = MT->CPU(); |
187 | cpu2 = MoniTool_Timer::Timer("_mt_amend_2_")->CPU(); |
188 | cput2 = MoniTool_Timer::Timer("_mt_amend_t2_")->CPU(); |
189 | cpu3 = MoniTool_Timer::Timer("_mt_amend_3_")->CPU(); |
190 | cput3 = MoniTool_Timer::Timer("_mt_amend_t3_")->CPU(); |
191 | |
192 | amExternal += ( cpu1 - cpu0 ) / NBTESTS; |
193 | amInternal += ( cput1 - cpu0 ) / NBTESTS; |
194 | amAccess += ( 0.5 * ( cpu3 - cpu1 ) ) / NBTESTS; |
195 | amError = Abs ( cpu1 + cpu3 - 2 * cpu2 ) / NBTESTS; |
196 | |
197 | cout << "CPU 0: " << cpu0 << endl; |
198 | cout << "CPU 1: " << cpu1 << " INTERNAL: " << cput1 << endl; |
199 | cout << "CPU 2: " << cpu2 << " INTERNAL: " << cput2 << endl; |
200 | cout << "CPU 3: " << cpu3 << " INTERNAL: " << cput3 << endl; |
201 | cout << "Access: " << amAccess << ", External: " << amExternal << |
202 | ", Internal: " << amInternal << ", Error: " << amError << endl; |
203 | |
204 | } |
205 | |
206 | //======================================================================= |
207 | //function : GetAmendments |
208 | //purpose : |
209 | //======================================================================= |
210 | |
211 | void MoniTool_Timer::GetAmendments (Standard_Real &access, |
212 | Standard_Real &internal, |
213 | Standard_Real &external, |
214 | Standard_Real &error10) |
215 | { |
216 | access = amAccess; |
217 | internal = amInternal; |
218 | external = amExternal; |
219 | error10 = amError; |
220 | } |
221 | |
222 | //======================================================================= |
223 | //function : AmendAccess |
224 | //purpose : |
225 | //======================================================================= |
226 | |
227 | static Handle(MoniTool_Timer) myActive; |
228 | |
229 | void MoniTool_Timer::AmendAccess () |
230 | { |
231 | Standard_Real amend = amAccess; |
232 | for ( Handle(MoniTool_Timer) act = myActive; ! act.IsNull(); act = act->myNext ) |
233 | act->myAmend += amend; |
234 | } |
235 | |
236 | void MoniTool_Timer::AmendStart () |
237 | { |
238 | Standard_Real amend = amExternal; |
239 | for ( Handle(MoniTool_Timer) act = myActive; ! act.IsNull(); act = act->myNext ) |
240 | act->myAmend += amend; |
241 | myAmend += amInternal; |
242 | |
243 | // add to list |
244 | if ( ! myActive.IsNull() ) { |
245 | myActive->myPrev = this; |
246 | myNext = myActive; |
247 | } |
248 | myActive = this; |
249 | } |
250 | |
251 | void MoniTool_Timer::AmendStop () |
252 | { |
253 | Handle (MoniTool_Timer) thisActive(this); |
254 | if ( myActive == thisActive ) myActive = myNext; |
255 | // if ( myActive == this ) myActive = myNext; |
256 | |
257 | if ( ! myPrev.IsNull() ) myPrev->myNext = myNext; |
258 | if ( ! myNext.IsNull() ) myNext->myPrev = myPrev; |
259 | |
260 | myNext = myPrev = 0; |
261 | } |