horometer.h
Go to the documentation of this file.
00001 // $Id$
00002 // Author: John Wu <John.Wu at ACM.org>
00003 // Copyright 2000-2011 the Regents of the University of California
00004 #ifndef IBIS_HOROMETER_H
00005 #define IBIS_HOROMETER_H
00006 #include <stdio.h>
00007 #include <time.h> // clock, clock_gettime
00008 #if defined(sun) || defined(linux) || defined(__HOS_AIX__) || \
00009     defined(__CYGWIN__) || defined(__APPLE__) || defined(__FreeBSD__)
00010 #   include <limits.h> // CLK_TCK
00011 #   include <sys/time.h> // gettimeofday, timeval
00012 #   include <sys/times.h> // times, struct tms
00013 #   include <sys/resource.h> // getrusage
00014 #   ifndef RUSAGE_SELF
00015 #       define RUSAGE_SELF 0
00016 #   endif
00017 #   ifndef RUSAGE_CHILDREN
00018 #       define RUSAGE_CHILDRED -1
00019 #   endif
00020 #elif defined(CRAY)
00021 #   include <sys/times.h> // times
00022 #elif defined(sgi)
00023 #   include <limits.h> // CLK_TCK
00024 #   define RUSAGE_SELF      0         /* calling process */
00025 #   define RUSAGE_CHILDREN  -1        /* terminated child processes */
00026 #   include <sys/times.h> // times
00027 //#   include <sys/types.h> // struct tms
00028 #   include <sys/time.h> // gettimeofday, getrusage
00029 #   include <sys/resource.h> // getrusage
00030 #elif defined(__MINGW32__)
00031 #   include <limits.h> // CLK_TCK
00032 #   include <sys/time.h> // gettimeofday, timeval
00033 #elif defined(_WIN32)
00034 #   include <windows.h>
00035 #elif defined(VMS)
00036 #   include <unistd.h>
00037 #endif
00038 
00041 namespace ibis {
00042     class horometer;
00043 }
00044 
00061 class ibis::horometer {
00062 public:
00063     horometer() : startRealTime(0), totalRealTime(0),
00064                   startCPUTime(0), totalCPUTime(0) {
00065 #if defined(_WIN32) && defined(_MSC_VER)
00066         // the frequency of the high-resolution performance counter
00067         LARGE_INTEGER lFrequency;
00068         BOOL ret = QueryPerformanceFrequency(&lFrequency);
00069         if (ret != 0 && lFrequency.QuadPart != 0)
00070             countPeriod = 1.0/static_cast<double>(lFrequency.QuadPart);
00071         else
00072             countPeriod = 0.0;
00073 #endif
00074     };
00076     void start() {
00077         startRealTime = readWallClock();
00078         startCPUTime = readCPUClock();
00079         totalRealTime = 0.0;
00080         totalCPUTime = 0.0;
00081     };
00083     void stop() {
00084         double tmpr = readWallClock() - startRealTime;
00085         double tmpc = readCPUClock() - startCPUTime;
00086         if (tmpr > 0.0)
00087             totalRealTime += tmpr;
00088         if (tmpc > 0.0)
00089             totalCPUTime += tmpc;
00090     };
00092     void resume() {
00093         startRealTime = readWallClock();
00094         startCPUTime = readCPUClock();
00095     }
00097     double realTime() const {return totalRealTime;}
00099     double CPUTime() const {return totalCPUTime;}
00100 
00101 private:
00102     double startRealTime;   // wall clock start time
00103     double totalRealTime;   // total real time
00104     double startCPUTime;    // cpu start time
00105     double totalCPUTime;    // total cpu time
00106 #if defined(_WIN32) && defined(_MSC_VER)
00107     double countPeriod;     // time of one high-resolution count
00108 #endif
00109 
00113     inline double readWallClock();
00116     inline double readCPUClock();
00117 };
00118 
00119 // read the system's wall clock time
00120 inline double ibis::horometer::readWallClock() {
00121 #if defined(CLOCK_REALTIME) && !defined(__CYGWIN__)
00122     struct timespec tb;
00123     if (0 == clock_gettime(CLOCK_REALTIME, &tb)) {
00124         return static_cast<double>(tb.tv_sec) + (1e-9 * tb.tv_nsec);
00125     }
00126     else {
00127         struct timeval cpt;
00128         gettimeofday(&cpt, 0);
00129         return static_cast<double>(cpt.tv_sec) + (1e-6 * cpt.tv_usec);
00130     }
00131 #elif defined(HAVE_GETTIMEOFDAY) || defined(unix) || defined(CRAY) || \
00132     defined(linux) || defined(__HOS_AIX__) || defined(__APPLE__) || \
00133     defined(__FreeBSD__)
00134     struct timeval cpt;
00135     gettimeofday(&cpt, 0);
00136     return static_cast<double>(cpt.tv_sec) + (1e-6 * cpt.tv_usec);
00137 #elif defined(_WIN32) && defined(_MSC_VER)
00138     double ret = 0.0;
00139     if (countPeriod != 0) {
00140         LARGE_INTEGER cnt;
00141         if (QueryPerformanceCounter(&cnt)) {
00142             ret = countPeriod * cnt.QuadPart;
00143         }
00144     }
00145     if (ret == 0.0) { // fallback option -- use GetSystemTime
00146         union {
00147             FILETIME ftFileTime;
00148             __int64  ftInt64;
00149         } ftRealTime;
00150         GetSystemTimeAsFileTime(&ftRealTime.ftFileTime);
00151         ret = (double) ftRealTime.ftInt64 * 1e-7;
00152     }
00153     return ret;
00154 #elif defined(VMS)
00155     return (double) clock() * 0.001;
00156 #else
00157     return (double) clock() / CLOCKS_PER_SEC;
00158 #endif
00159 } //  ibis::horometer::readWallClock
00160 
00161 // read the value of the CPU clock time
00162 inline double ibis::horometer::readCPUClock() {
00163 #if defined(sun) || defined(sgi) || defined(linux) || defined(__APPLE__) \
00164     || defined(__HOS_AIX__) || defined(__CYGWIN__) || defined(__FreeBSD__)
00165     // on sun and linux, we can access getrusage to get more accurate time
00166     double time=0;
00167     struct rusage ruse;
00168     if (0 == getrusage(RUSAGE_SELF, &ruse)) {
00169         time = (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec) * 1e-6 +
00170             ruse.ru_utime.tv_sec + ruse.ru_stime.tv_sec;
00171     }
00172     else {
00173         fputs("Warning -- horometer::readCPUClock(): getrusage failed "
00174               "on RUSAGE_SELF", stderr);
00175     }
00176     if (0 == getrusage(RUSAGE_CHILDREN, &ruse)) {
00177         time += (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec) * 1e-6 +
00178             ruse.ru_utime.tv_sec + ruse.ru_stime.tv_sec;
00179     }
00180     else {
00181         fputs("Warning -- horometer::readCPUClock(): getrusage failed on "
00182               "RUSAGE_CHILDRED", stderr);
00183     }
00184     return time;
00185 #elif defined(unix) || defined(CRAY)
00186 #if defined(__STDC__)
00187     struct tms cpt;
00188     times(&cpt);
00189     return (cpt.tms_utime + cpt.tms_stime + cpt.tms_cutime +
00190             (double)cpt.tms_cstime) / CLK_TCK;
00191 #else
00192     return (double) times() / CLK_TCK;
00193 #endif
00194 #elif defined(_WIN32)
00195     return (double) clock() / CLOCKS_PER_SEC;
00196 #elif defined(VMS)
00197     return (double) clock() * 0.001;
00198 #else
00199     return (double) clock() / CLOCKS_PER_SEC;
00200 #endif
00201 } // ibis::horometer::readCPUClock
00202 #endif // IBIS_HOROMETER_H

Make It A Bit Faster
Contact us
Disclaimers
FastBit source code
FastBit mailing list archive