00001 // $Id$ 00002 // Author: John Wu <John.Wu at ACM.org> 00003 // Copyright 2000-2009 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
![]() |