- Main Page
- Classes
- Files

- File List
- File Members

# Timer.h

Go to the documentation of this file.

    00001
    00028 #ifndef Timer_h
    00029 #define Timer_h
    00030 //----------------------------------------------------------------------
    00031 #include <iostream>
    00032 #include <stdio.h>
    00033 #include <time.h>
    00034
    00035 #ifndef WIN32
    00036 #  include <sys/time.h>
    00037 #  include <sys/times.h>
    00038 #  include <unistd.h>
    00039 #endif
    00040
    00041 using namespace std;
    00042 //----------------------------------------------------------------------
    00044 class Timer {
    00045   private:
    00046     static long    indent;
    00047     //for summary stats
    00048     static double  best;
    00049     static double  worst;
    00050     static double  total;
    00051     static long    count;
    00052
    00053     double  mStart;
    00054     #ifdef WIN32
    00055         //long            tc_start;
    00056         FILETIME  mKernelTime, mUserTime;
    00057     #else
    00058         //struct timeval  tv_start;
    00059         struct tms  mStartUsage;
    00060     #endif
    00061     char*  msg;
    00062     bool   summary;
    00063
    00064   public:
    00065     inline Timer ( const bool summary=false ) {
    00066         Timer( (char*)NULL, summary );
    00067     }
    00068     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    00069     inline Timer ( char* m, const bool summary=false ) {
    00070         //init our "timer" to determine how long will this take.
    00071         ++Timer::indent;
    00072         this->msg = m;
    00073         this->summary = summary;
    00074         reset();
    00075     }
    00076     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    00078     inline void reset ( void ) {
    00079         #ifdef WIN32
    00080             mStart = GetTickCount();
    00081
    00082             FILETIME  creationTime, exitTime;
    00083             GetProcessTimes( GetCurrentProcess(), &creationTime, &exitTime,
    00084                 &mKernelTime, &mUserTime );
    00085         #else
    00086             struct timeval   tv_start;
    00087             struct timezone  tz_start;
    00088             gettimeofday( &tv_start, &tz_start );
    00089             mStart = tv_start.tv_sec + (tv_start.tv_usec / 1E6);
    00090
    00091             times( &mStartUsage );
    00092         #endif
    00093     }
    00094     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    00096     inline double getElapsedTime ( void ) {
    00097         #ifdef WIN32
    00098             long  tc_end = GetTickCount();
    00099             return  (tc_end-mStart) / 1E3;
    00100         #else
    00101             struct timeval  tv_end;
    00102             struct timezone tz_end;
    00103             gettimeofday(&tv_end, &tz_end);
    00104             double d_end   = tv_end.tv_sec + (tv_end.tv_usec / 1E6);
    00105             return (d_end-mStart);
    00106         #endif
    00107     }
    00108     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    00111     inline void report ( void ) {
    00112         for (int i=0; i<Timer::indent; i++)    cout << "  ";
    00113         if (this->msg != NULL) {
    00114             cout << this->msg << " ";
    00115         }
    00116         cout << "elapsed time=" << getElapsedTime() << "s,";
    00117         cout << " CPU time=" << getCPUTime() << "s";
    00118
    00119         if (this->summary) {
    00120             cout << ", best=" << Timer::best << ", worst=" << Timer::worst
    00121                  << ", average=" << (Timer::total/Timer::count);
    00122         }
    00123
    00124         cout << endl;
    00125     }
    00126     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    00128     inline double getCPUTime ( void ) {
    00129       #ifdef  WIN32
    00130         FILETIME  creationTime, exitTime, kernelTime, userTime;
    00131         GetProcessTimes( GetCurrentProcess(), &creationTime, &exitTime,
    00132             &kernelTime, &userTime );
    00133         //as recommended by bill:
    00134         // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/filetime_str.asp
    00135         ULARGE_INTEGER  u2;
    00136         memcpy( &u2, &userTime, sizeof(userTime) );
    00137         __int64*  i2 = (__int64*)&u2;
    00138         ULARGE_INTEGER  u1;
    00139         memcpy( &u1, &mUserTime, sizeof(mUserTime) );
    00140         __int64*  i1 = (__int64*)&u1;
    00141         __int64   i3 = *i2 - *i1;
    00142         //from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/filetime_str.asp
    00143         // The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).
    00144         const double  userCPUTime = i3 * 100 / 1E9;
    00145
    00146         //determine kernel cpu time
    00147         memcpy( &u2, &kernelTime, sizeof(kernelTime) );
    00148         i2 = (__int64*)&u2;
    00149         memcpy( &u1, &mKernelTime, sizeof(mKernelTime) );
    00150         i1 = (__int64*)&u1;
    00151         i3 = *i2 - *i1;
    00152         const double  kernelCPUTime = i3 * 100 / 1E9;
    00153
    00154         return userCPUTime + kernelCPUTime;
    00155       #else
    00156         struct tms  usageAfter;
    00157         times( &usageAfter );
    00158         double  cpuTime = ((double)usageAfter.tms_utime - mStartUsage.tms_utime)
    00159                                  / sysconf(_SC_CLK_TCK);
    00160         cpuTime += ((double)usageAfter.tms_stime - mStartUsage.tms_stime)
    00161                                  / sysconf(_SC_CLK_TCK);
    00162         return cpuTime;
    00163       #endif
    00164     }
    00165     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    00166     inline ~Timer ( ) {
    00167         const double t = getElapsedTime();
    00168         if (this->summary) {
    00169             Timer::total += t;
    00170             ++Timer::count;
    00171             if (t>Timer::worst)  Timer::worst=t;
    00172             if (t<Timer::best)   Timer::best =t;
    00173         }
    00174         report();
    00175         --Timer::indent;
    00176     }
    00177 };
    00178
    00179 long   Timer::indent = 0;
    00180 double Timer::best   = FLT_MAX;
    00181 double Timer::worst  = 0.0;
    00182 double Timer::total  = 0.0;
    00183 long   Timer::count  = 0;
    00184
    00185 #endif
    00186 //----------------------------------------------------------------------