Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TimeMeasure.cpp
1 #include "TimeMeasure.hh"
2 
3 #ifdef WIN32
4 # include <Windows.h>
5 # pragma warning (disable: 4996)
6 #endif
7 
8 using namespace std;
9 using namespace BIAS;
10 
11 // this file only to instantiate this static member:
13 
14 
15 // JW, woelk
16 TimeMeasure::TimeMeasure()
17 {
18  timerclear(&rtRealSum);
19  timerclear(&rtKernelSum);
20  timerclear(&rtLast);
21  timerclear(&rtActual);
22 
23  user = 0;
24  running = false;
25  _dSum=0.0;
26 
27 #ifdef WIN32
28  kernel = 0;
29  idle = 0;
30  _tscStart = _tscEnd = _tscTicks = 0;
31 #else // WIN32
32 # ifdef __i386__
33  _uiHiStart=_uiLoStart=_uiHiStop=_uiLoStop=0;
34 # endif
35 #endif //WIN32
36 }
37 
38 
39 #ifdef WIN32 //Start and Stop not inlined for Win32
40 
41  void TimeMeasure::Start() {
42 # ifdef BIAS_DEBUG
43  if(running) BIASERR("clock already started");
44 # endif // BIAS_DEBUG
45  running = true;
46 
47  //** NOT IMPLEMENTED CORRECTLY?
48  if ((rtLast.tv_usec=clock()) == -1)
49  BIASERR("error starting real timer "<<errno);
50 
51  // convert from msec to microsecs
52  rtLast.tv_usec *= (int)(1E6/CLOCKS_PER_SEC);
53 
54  _tscStart = BIAS::GetTSC();
55 
56 # if _WIN32_WINNT >= 0x0501 // see winbase.h
57  GetSystemTimes(&_IdleTimeStart, &_KernelTimeStart, &_UserTimeStart);
58 # else //_WIN32_WINNT >= 0x0501
59  _IdleTimeStart.dwHighDateTime = 0;
60  _IdleTimeStart.dwLowDateTime = 0;
61  _KernelTimeStart.dwHighDateTime = 0;
62  _KernelTimeStart.dwLowDateTime = 0;
63  _UserTimeStart.dwHighDateTime = 0;
64  _UserTimeStart.dwLowDateTime = 0;
65  BIASWARN("You need at least WinXP/Server2003 to ge system times!");
66 # endif //_WIN32_WINNT >= 0x0501
67 }
68 
69 void TimeMeasure::Stop() {
70 
71  if(running) {
72  //** NOT IMPLEMENTED CORRECTLY?
73  _tscEnd=BIAS::GetTSC();
74 
75  // CRT clock() return the elapsed CPU time sonce process start
76  // which is a realtime, *not* CPU computing time which is displayed in
77  // task manager! (JW)
78  if ((rtActual.tv_usec=clock()) == -1)
79  {
80  BIASERR("error stoping real timer "<<errno);
81  }
82  // convert from msec to microsecs
83  rtActual.tv_usec *= (int)(1E6/CLOCKS_PER_SEC);
84 
85 # if _WIN32_WINNT >= 0x0501 // see winbase.h
86  GetSystemTimes(&_IdleTimeStop, &_KernelTimeStop, &_UserTimeStop);
87 # else //_WIN32_WINNT >= 0x0501
88  _IdleTimeStop.dwHighDateTime = 0;
89  _IdleTimeStop.dwLowDateTime = 0;
90  _KernelTimeStop.dwHighDateTime = 0;
91  _KernelTimeStop.dwLowDateTime = 0;
92  _UserTimeStop.dwHighDateTime = 0;
93  _UserTimeStop.dwLowDateTime = 0;
94  BIASWARN("You need at least WinXP/Server2003 to ge system times!");
95 # endif //_WIN32_WINNT >= 0x0501
96 
97  FILETIME diffUserTime, diffKernelTime, diffIdleTime;
98 
99  // Compute time that system spended in user, kernel and idle mode
100  diffUserTime.dwHighDateTime =
101  _UserTimeStop.dwHighDateTime - _UserTimeStart.dwHighDateTime;
102  diffUserTime.dwLowDateTime =
103  _UserTimeStop.dwLowDateTime - _UserTimeStart.dwLowDateTime;
104  diffKernelTime.dwHighDateTime =
105  _KernelTimeStop.dwHighDateTime - _KernelTimeStart.dwHighDateTime;
106  diffKernelTime.dwLowDateTime =
107  _KernelTimeStop.dwLowDateTime - _KernelTimeStart.dwLowDateTime;
108  diffIdleTime.dwHighDateTime =
109  _IdleTimeStart.dwHighDateTime - _IdleTimeStart.dwHighDateTime;
110  diffIdleTime.dwLowDateTime =
111  _IdleTimeStart.dwLowDateTime - _IdleTimeStart.dwLowDateTime;
112 
113  // convert to system time an derive new user time in ms
114  SYSTEMTIME userUTC, kernelUTC, idleUTC;
115 
116  // compute time that system spended in user, kernel and idle mode
117  FileTimeToSystemTime(&diffUserTime, &userUTC);
118  FileTimeToSystemTime(&diffKernelTime, &kernelUTC);
119  FileTimeToSystemTime(&diffIdleTime, &idleUTC);
120  user += (userUTC.wMilliseconds + 1000 * userUTC.wSecond +
121  60*1000 * userUTC.wMinute + 60*60*1000*userUTC.wHour);
122  kernel += (kernelUTC.wMilliseconds + 1000 * kernelUTC.wSecond +
123  60*1000 * kernelUTC.wMinute + 60*60*1000*kernelUTC.wHour);
124  idle += (idleUTC.wMilliseconds + 1000 * idleUTC.wSecond +
125  60*1000 * idleUTC.wMinute + 60*60*1000*idleUTC.wHour);
126 
127  rtRealSum.tv_sec += (rtActual.tv_usec - rtLast.tv_usec) / ((int)1E6);
128  rtRealSum.tv_usec += (rtActual.tv_usec - rtLast.tv_usec) % ((int)1E6);
129  //cerr << "stopstruct.tms_utime: " << stopstruct.tms_utime << endl;
130 
131  _tscTicks = BIAS::GetTSCTicks(_tscStart, _tscEnd);
132  _dSum += _tscTicks;
133  running = false;
134  } else {
135  BIASERR("cannot stop clock befor starting it");
136  BIASASSERT(running);
137  }
138  }
139 #endif // WIN32
140 
141 // JW
142 //static
143 void TimeMeasure::
144 MSecondsToHumanReadable(const unsigned long & msIN, int & msecOUT,
145  int & seconds, int & minutes, int & hours,
146  int & days, int & weeks)
147 {
148  unsigned long rest = msIN; // remainder
149 
150  msecOUT = rest % 1000; // 1000 msec each second
151  rest -= msecOUT;
152  rest /= 1000; // now seconds
153 
154  seconds = rest % 60; // 60 seconds each minute
155  rest -= seconds;
156  rest /= 60; // now minutes
157 
158  minutes = rest % 60;// 60 minutes each hour
159  rest -= minutes;
160  rest /= 60; // now hours
161 
162  hours = rest % 24;// 24 hours each day
163  rest -= hours;
164  rest /= 24; // now days
165 
166  days = rest % 7;// 7 days a week
167  rest -= days;
168  rest /= 7; // now week
169 
170  weeks = rest;
171  // do not split further
172  // because days pe rmonth vary (28-31 days, const 365 day year is too long for me to wait anyhow ;-)
173 }
174 
175 //JW
176 //static
177 std::ostream & TimeMeasure::
178 PrintMsecHumanReadable(const unsigned long msecIN, std::ostream &os)
179 {
180  int ms, sec, minutes, hh, dd, ww;
181  MSecondsToHumanReadable(msecIN, ms, sec, minutes, hh, dd, ww);
182 
183  bool display=false;
184  if (ww>0) display=true;
185  if (display) os<<setw(3)<<ww<<" weeks ";
186 
187  if (hh>0) display=true;
188  if (display) os<<setw(3)<<dd<<" days ";
189 
190  if (dd>0) display=true;
191  if (display) os<<setw(3)<<hh<<" hours ";
192 
193  if (minutes>0) display=true;
194  if (display) os<<setw(3)<<minutes<<" minutes ";
195 
196  if (sec>0) display=true;
197  if (display) os<<setw(3)<<sec<<" sec ";
198 
199  if (!display){
200  // display zero at least:
201  os<<setw(3)<<ms<<" msec";
202  } else if (ms>0){
203  // suppress displaying 0 msec.
204  os<<setw(3)<<ms<<" msec";
205  };
206 
207  return os;
208 }
209 
210 std::string TimeMeasure::
211 GetCurrentTimeAsString(){
212  time_t rawtime;
213  struct tm * timeinfo;
214  char buffer [80];
215 
216  time ( &rawtime );
217  timeinfo = localtime ( &rawtime );
218  //see http://www.cplusplus.com/reference/clibrary/ctime/strftime/
219  strftime (buffer,80,"%X",timeinfo);
220  return string(buffer);
221 }
222 
223 std::string TimeMeasure::
224 GetDateAsString(){
225  time_t rawtime;
226  struct tm * timeinfo;
227  char buffer [80];
228 
229  time ( &rawtime );
230  timeinfo = localtime ( &rawtime );
231  //see http://www.cplusplus.com/reference/clibrary/ctime/strftime/
232  strftime (buffer,80,"%x",timeinfo);
233  return string(buffer);
234 }
235 
236 
237 
238 double TimeMeasure::
239 MeasureOverhead()
240 {
241  /* Do it twice to eliminate cache effects */
242  int i;
243  double result=0;
244 
245  for (i = 0; i < 2; i++) {
246  Reset();
247  Start();
248  Stop();
249  result = GetCycleCount();
250  }
251  return result;
252 }
253 
254 double TimeMeasure::
255 MeasureProcessorFrequency()
256 {
257  double rate;
258  int sleeptime=2;
259 
260  Start();
261 #ifdef WIN32
262  Sleep(sleeptime *1000);
263 #else
264  sleep(sleeptime);
265 #endif
266  Stop();
267  rate = GetCycleCount() / (1e6*sleeptime);
268 
269  return rate;
270 }
271 
272 void TimeMeasure::
273 PrintRealTime(std::ostream& os, const bool &verbose) const
274 {
275  os<<"real: "
276  <<std::setw(12)
277  <<GetRealTime()<<" us ";
278  if (verbose) {
279  os<<"\t(";
280  PrintMsecHumanReadable( long(GetRealTime() /1000.0 ), os);
281  os<<")";
282  }
283  os<<std::endl;
284 }
285 
286 void TimeMeasure::
287 PrintUserTime(std::ostream& os, const bool & verbose) const
288 {
289  os << "user: "
290  <<std::setw(12)
291  <<GetUserTime()<<" ms ";
292  if (verbose) {
293  //os<<" "; // align with printrealtime
294  os<<"\t(";
295  PrintMsecHumanReadable( long(GetUserTime()), os);
296  os<<")";
297  }
298  os<<std::endl;
299 }
300 
301 void TimeMeasure::
302 PrintKernelTime(std::ostream& os, const bool & verbose) const
303 {
304  os << "kernel: "
305  <<std::setw(12)
306  <<GetKernelTime()<<" ms ";
307  if (verbose) {
308  os<<"\t(";
309  PrintMsecHumanReadable( long(GetKernelTime()), os);
310  os<<")";
311  }
312  os<<std::endl;
313 }
314 
315 void TimeMeasure::
316 PrintIdleTime(std::ostream& os, const bool & verbose) const
317 {
318  os << "idle: "
319  <<std::setw(12)
320  <<GetIdleTime()<<" ms ";
321  if (verbose) {
322  os<<"\t(";
323  PrintMsecHumanReadable( long(GetIdleTime()), os);
324  os<<")";
325  }
326  os<<std::endl;
327 }
328 
329 void TimeMeasure::
330 PrintCycleCount(std::ostream& os) const
331 {
332  os << "cycles: "
333  <<std::setw(14)
334  <<GetCycleCount()<<std::endl;
335 }
336 
337 void TimeMeasure::
338 CloseTimerFile()
339 {
340  TimerStream_.close();
341 }
342 
343 
344 void TimeMeasure::
345 SetTimerFile(const std::string &file)
346 {
347  // if (TimerStream_) TimerStream_.close();
348  TimerStream_.open(file.c_str(), std::ios_base::app);
349  if (!TimerStream_) {
350  BIASERR("Can not open TimerFile "<<file
351  <<" in TimeMeasure::SetTimerFile()")
352  perror(file.c_str());
353  BIASABORT;
354  }
355 }
356 
357 void TimeMeasure::
358 LogToFileAndReset(const std::string &comment)
359 {
360  Stop();
361  if (!TimerStream_) BIASERR("TimerStream_ not open");
362  TimerStream_<<"real: "<<std::setw(10)<<GetRealTime()/1e3
363  <<"\tuser: "<<std::setw(6)<<GetUserTime()
364  <<"\t"<<comment<<std::endl;
365  Reset();
366 }
367 
368 
369 double TimeMeasure::
370 GetRealTime() const
371 {
372  return (double)(rtRealSum.tv_usec + (rtRealSum.tv_sec*1E6));
373 }
374 
375 double TimeMeasure::
376 GetUserTime() const
377 {
378  //cerr << "sysconf(_SC_CLK_TCK): " << sysconf(_SC_CLK_TCK) << endl;
379  // see ` man 2 times`
380 #ifdef WIN32
381  return (double)user;// /(double)CLOCKS_PER_SEC * 1e3; already ms
382 #else // WIN32
383  return (double)user/(double)sysconf(_SC_CLK_TCK) * 1e3;
384 #endif // WIN32
385 }
386 
387 double TimeMeasure::GetKernelTime() const
388 {
389 #ifdef WIN32
390  return (double)kernel;// /(double)CLOCKS_PER_SEC * 1e3; already ms
391 #else // WIN32
392  return 0.0;
393 #endif // WIN32
394 }
395 
396 double TimeMeasure::GetIdleTime() const
397 {
398 #ifdef WIN32
399  return (double)idle; // /(double)CLOCKS_PER_SEC * 1e3; already ms
400 #else // WIN32
401  return 0.0;
402 #endif // WIN32
403 }
404 
405 double TimeMeasure::GetFreq() const
406 {
407  return 1E6/GetRealTime();
408 }
409 
410 double TimeMeasure::GetUserFreq() const
411 {
412  return 1E3/GetUserTime();
413 }
414 
415 bool TimeMeasure::IsRunning() const
416 {
417  return running;
418 }
419 
420 
421 double TimeMeasure::GetCycleCount() const
422 {
423 #ifdef BIAS_DEBUG
424  if(running) {
425  BIASERR("you called GetCycleCount() while timer is running");
426  }
427 #endif
428  return _dSum;
429 }
430 
431 
432 void TimeMeasure::Reset()
433 {
434  if (running){
435  BIASERR("cannot reset running TimeMeasure");
436  } else {
437 #ifdef WIN32
438  _tscStart = _tscEnd = _tscTicks = 0;
439  kernel = 0;
440  idle = 0;
441 #else // WIN32
442 # ifdef __i386__
443  _uiHiStart=_uiLoStart=_uiHiStop=_uiLoStop=0;
444 # endif // __i386__
445 #endif // WIN32
446 
447  _dSum=0.0;
448  timerclear(&rtRealSum);
449  timerclear(&rtKernelSum);
450  user = 0;
451  }
452 }
453 
454 
455 void TimeMeasure::Print(std::ostream& os) const
456 {
457  PrintRealTime(os);
458  PrintUserTime(os);
459 #ifdef WIN32
460  PrintKernelTime(os);
461  PrintIdleTime(os);
462 #endif //WIN32
463  PrintCycleCount(os);
464 }
465 
466 
467 
static std::ofstream TimerStream_
Definition: TimeMeasure.hh:284