Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TimeMeasure.hh
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5 Multimediale Systeme der Informationsverarbeitung
6 Institut fuer Informatik
7 Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 #ifndef _TIMEMEASURE_H_261946892_
27 #define _TIMEMEASURE_H_261946892_
28 
29 #ifdef WIN32
30 
31 # ifndef _WIN32_WINNT
32 # define _WIN32_WINNT 0x0501 // Windows XP for GetSystemTimes
33 # endif // _WIN32_WINNT
34 
35 # include <time.h>
36 # include <Base/Common/W32Compat.hh>
37 
38 struct tms {
39  clock_t tms_utime; /* user time */
40  clock_t tms_stime; /* system time */
41  clock_t tms_cutime; /* user time of children */
42  clock_t tms_cstime; /* system time of children */
43 };
44 
45 #else // WIN32
46 
47 // Linux
48 # include <sys/time.h>
49 # include <sys/times.h>
50 # include <unistd.h>
51 
52 #endif // WIN32
53 
54 
55 #include <fstream>
56 #include <errno.h>
57 #include <stdlib.h>
58 #include <limits.h>
59 
60 // stl strings:
61 #include <string>
62 #include <iostream>
63 
64 // debugging information
65 #include "Debug.hh"
66 #include "Error.hh"
67 
68 
69 namespace BIAS {
70 
71 #ifdef WIN32
72  /** @brief get "Time Stamp Counter" on Pentium like CPU's.
73  Assembler function without prolog and epilog.
74  Should work on Intel Pentium and newer AMD CPU's, see rdtsc assembler
75  instruction.
76  This functions can't be class member inlined because it collides with
77  naked fastcall.
78  \todo cleanup TimeMeasure class in platform independant manner. (JW)
79  \bug user/system time is implemented wrong on WIN32. see time and clock
80  functions (JW)
81 
82  @returns the number of clock cycles since the CPU was powered up or
83  reset.
84  @author Jan Woetzel, 12/2004 */
85  // int64 has no ANSI equivalent (JW)
86  // fallback workaround implementation
87 #ifdef _WIN64
88  __forceinline __int64 __fastcall GetTSC(){ return __rdtsc(); };
89 #else
90  __forceinline __int64 __fastcall GetTSC(){ __asm rdtsc };
91 #endif
92 
93  /** @brief compute the difference between two int64 cycle counts using 12
94  bit overflow mask .
95  @author Jan Woetzel 12/2004 */
96  inline __int64 GetTSCTicks(__int64 start, __int64 end)
97  {return ((end - start) & 0xFFFFFFFFFFFF);};
98 #endif // WIN32
99 
100  /** @class TimeMeasure
101  @ingroup g_utils
102  @brief class TimeMeasure contains functions for timing real time and
103  cpu time.
104 
105  added Win32 rdtsc assembler cycle count with int64 jw 12/2004
106  added Linux cycle count functions for i386-processors woelk 07/2003
107 
108  For Win32 the minimum requiered version is 0x0501 (WinXP/Server2005)
109 
110  @author Jan Woetzel (03/04/2002 - 11/2005) **/
111  class BIASDebug_EXPORT TimeMeasure {
112 
113  public:
114  /// default constructor:
115  TimeMeasure();
116 
117  /// print the output when the desctructor is called ?
119 
120 //Sorry for that ifdef-mess but WIN32 has no suitable
121 //timer functions!
122 #ifdef WIN32
123  //Inline not possible for win32-implementation
124  void Start();
125 
126  void Stop();
127 #else // WIN32
128  inline void Start();
129 
130  inline void Stop();
131 #endif // WIN32
132 
133  void Print(std::ostream& os=std::cout) const;
134 
135  void Reset();
136 
137  /** return real time (=wall time clock) in usec JW
138  For Win32: real-time is measured differently from
139  user-/kernel-time. Don't wonder about
140  small inconsistancies!
141  */
142  double GetRealTime() const;
143 
144  /** return user time (=system usage time) in msec JW
145  For Win32: user-time is the sum over all processes on
146  all processors in user-mode
147  (not only the calling process!)
148  */
149  double GetUserTime() const;
150 
151  /** WIN32: return time that system spended in kernel mode in msec cmenk
152  = Sum over all processes on all processors in kernel mode
153  (!!!including the system idle process!!!)
154  */
155  double GetKernelTime() const;
156 
157  /** WIN32: return time that system spended in idle mode in msec cmenk
158  Seems to be a bit useless
159  */
160  double GetIdleTime() const;
161 
162  /** returns the frequency in Hz based on real time (= fps)*/
163  double GetFreq() const;
164 
165  /** returns the frequency in Hz based on user time (= fps)*/
166  double GetUserFreq() const;
167 
168  /** print the real time (=wall time clok)
169  @param verbose true for additionoutput in days hour sminutes seconds
170  Jan Woetzel */
171  void PrintRealTime(std::ostream& os=std::cout,
172  const bool &verbose=true) const;
173 
174  /** print the user time (=system usage time)
175  @param verbose true for additionoutput in days hour sminutes seconds
176  Jan Woetzel */
177  void PrintUserTime(std::ostream& os=std::cout,
178  const bool &verbose=true) const;
179 
180  /** print the time that the system spended in kernel mode (WIN32)
181  @param verbose true for additionoutput in days hour sminutes seconds
182  cmenk */
183  void PrintKernelTime(std::ostream& os=std::cout,
184  const bool &verbose=true) const;
185 
186  /** print the time that the system spended in idle mode
187  @param verbose true for additionoutput in days hour sminutes seconds
188  cmenk */
189  void PrintIdleTime(std::ostream& os=std::cout,
190  const bool & verbose=true) const;
191 
192  bool IsRunning() const;
193 
194  void SetTimerFile(const std::string &file);
195  void LogToFileAndReset(const std::string &comment);
196  void CloseTimerFile();
197 
198  /** return number of cycles between all subsequent calls
199  to Start() and Stop() since last call to Reset()
200  @author woelk */
201  double GetCycleCount() const;
202 
203  /** prints the number of cycles between subsequent
204  calls to Start() and Stop() since last call to Reset() to os
205  @author woelk */
206  void PrintCycleCount(std::ostream& os=std::cout) const ;
207 
208  /* Set *hi and *lo to the high and low order bits of the cycle counter.
209  Implementation requires assembly code to use the rdtsc instruction.
210  @author woelk (Linux), Win32 by Jan Woetzel */
211  inline void ReadCycleCounter(unsigned int *hi, unsigned int *lo);
212 
213 
214  /** returns the number of cycles between subsequent Start() and Stop()
215  calls !! implies a Reset(); !!!
216  @author woelk */
217  double MeasureOverhead();
218 
219  /** measures the ProcessorFrequency in MHz
220  @author woelk */
221  double MeasureProcessorFrequency();
222 
223 
224  /** converts a given amount of millisecs to human redable format
225 
226  extracts hours, minutes, seconds, msecs from amout of msecs
227  (1/1000 sec).
228  @param msecIN input parameter
229  @author Jan Woetzel */
230  static void MSecondsToHumanReadable(const unsigned long & msIN,
231  int & msecOUT, int & seconds,
232  int & minutes, int & hours,
233  int & days, int & weeks );
234 
235 
236  /** display nr of msecs in format weeks,days,hours,minutes,seconds */
237  static std::ostream & PrintMsecHumanReadable(const unsigned long msecIN,
238  std::ostream &os=std::cout);
239  /**
240  * \brief Obtains the current time and returns as string.
241  * For alternative formats see:
242  * http://www.cplusplus.com/reference/clibrary/ctime/strftime/
243  * \author Ingo Schiller
244  * \date 04/2011
245  */
246  static std::string GetCurrentTimeAsString();
247  /**
248  * \brief Obtains the current date and returns as string.
249  * For alternative formats see:
250  * http://www.cplusplus.com/reference/clibrary/ctime/strftime/
251  * \author Ingo Schiller
252  * \date 04/2011
253  */
254  static std::string GetDateAsString();
255 
256  protected:
257  timeval rtRealSum;
258  timeval rtLast;
259  timeval rtActual;
260  timeval rtKernelSum;
261  clock_t user; // user time
262  struct tms startstruct, stopstruct; // see `man 2 times`
263  bool running; // boolean to tell wether the clock is running or not
264 
265 #ifdef WIN32
266  FILETIME _UserTimeStart, _UserTimeStop;
267  FILETIME _KernelTimeStart, _KernelTimeStop;
268  FILETIME _IdleTimeStart, _IdleTimeStop;
269  clock_t kernel; // kernel time
270  clock_t idle; // idle time
271 #endif // WIN32
272 
273  double _dSum;
274 
275 #ifdef WIN32
276  __int64 _tscStart, _tscEnd, _tscTicks;
277 #else // WIN32
278 # ifdef __i386__
279  unsigned int _uiHiStart, _uiLoStart, _uiHiStop, _uiLoStop;
280 # endif // __i386__
281 #endif // WIN32
282 
283  // have one file stream to log to for all timer instances
284  static std::ofstream TimerStream_;
285 
286  }; // class -----------------------------------
287 
288 
289  //
290  // inline IMPLEMENTATIONs
291  //
292 
293 #ifndef WIN32
294  inline void TimeMeasure::Start()
295  {
296 # ifdef BIAS_DEBUG
297  if(running) BIASERR("clock already started");
298 # endif // BIAS_DEBUG
299 
300  running = true;
301 
302  gettimeofday(&rtLast,NULL);
303  if (times(&startstruct) == (clock_t)(-1))
304  BIASERR("error starting user timer "<<errno);
305 
306 # ifdef __i386__
307  ReadCycleCounter(&_uiHiStart, &_uiLoStart);
308 # endif //__i386__
309  }
310 
311 
312  inline void TimeMeasure::Stop()
313  {
314  if(running) {
315 
316 # ifdef __i386__
317  ReadCycleCounter(&_uiHiStop, &_uiLoStop);
318 # endif // __i386__
319 
320  gettimeofday(&rtActual, NULL);
321  if (times(&stopstruct) == (clock_t)(-1)){
322  BIASERR("error stopping user timer "<<errno);
323  }
324  //cerr << "stop s: "<<rtActual.tv_sec<<"\tus: "<<rtActual.tv_usec
325  //<<std::endl;
326  rtRealSum.tv_sec += rtActual.tv_sec - rtLast.tv_sec;
327  long usec;
328  if (rtActual.tv_usec > rtLast.tv_usec) {
329  usec = rtActual.tv_usec - rtLast.tv_usec;
330  } else {
331  usec = 1000000-rtLast.tv_usec+rtActual.tv_usec;
332  rtRealSum.tv_sec--;
333  }
334  rtRealSum.tv_usec += usec;
335  // cerr << "act s: "<<rtActual.tv_sec<<"\tus: "<<rtActual.tv_usec<<endl;
336  // cerr << "lst s: "<<rtLast.tv_sec<<"\tus: "<<rtLast.tv_usec<<endl;
337  // cerr<<"stop s: "<<rtRealSum.tv_sec<<"\tus: "<<rtRealSum.tv_usec<<endl;
338 
339  user += stopstruct.tms_utime - startstruct.tms_utime;
340 
341  //cerr << "stopstruct.tms_utime: " << stopstruct.tms_utime << endl;
342 
343 # ifdef __i386__
344  double count;
345  if (_uiLoStop>_uiLoStart)
346  count = ((double)_uiHiStop-(double)_uiHiStart)*(double)UINT_MAX+
347  (double)_uiLoStop-(double)_uiLoStart;
348  else
349  count = ((double)_uiHiStop-(double)_uiHiStart-1)*(double)UINT_MAX+
350  (double)_uiLoStop+(double)UINT_MAX-(double)_uiLoStart;
351  _dSum+=count;
352 # endif //__i386__
353 
354  running = false;
355  } else {
356  BIASERR("cannot stop clock befor starting it");
357  BIASASSERT(running);
358  }
359  }
360 
361 # ifdef __i386__
362  inline
363  void TimeMeasure::ReadCycleCounter(unsigned int *hi, unsigned int *lo)
364  {
365  // Linux: Felix
366  // see BIAS::GetTSC for WIN32 equivalent (jw)
367  asm("rdtsc; movl %%edx,%0; movl %%eax,%1" /* Read cycle counter */
368  : "=r" (*hi), "=r" (*lo) /* and move results to */
369  : /* No input */ /* the two outputs */
370  : "%edx", "%eax");
371  }
372 # endif // __i386__
373 #endif // not WIN32
374 
375 } // namespace
376 #endif // _TIMEMEASURE_H_261946892_
377 
~TimeMeasure()
print the output when the desctructor is called ?
Definition: TimeMeasure.hh:118
struct tms startstruct stopstruct
Definition: TimeMeasure.hh:262
void ReadCycleCounter(unsigned int *hi, unsigned int *lo)
static std::ofstream TimerStream_
Definition: TimeMeasure.hh:284
class TimeMeasure contains functions for timing real time and cpu time.
Definition: TimeMeasure.hh:111