00001 #ifndef MISC_PERFMON_H
00002 #define MISC_PERFMON_H
00003 #if defined(__i386__) || defined(__x86_64__) || defined(_MSC_VER)
00004 # define HAVE_TSC 1
00005 #endif
00006 #ifndef _MSC_VER
00007 # include <sys/time.h>
00008 # ifndef HAVE_TSC
00009 # include <sys/resource.h>
00010 # endif
00011 #endif
00012 #include <iosfwd>
00013 #include <string>
00014 #include <cassert>
00015 namespace osl
00016 {
00017 namespace misc
00018 {
00019 class PerfMon
00020 {
00021 #ifdef HAVE_TSC
00022 unsigned long long start_time;
00023 #else
00024 rusage start_time;
00025 #endif
00026 public:
00027 void restart()
00028 {
00029 #ifdef HAVE_TSC
00030 # ifndef _MSC_VER
00031 unsigned int ax,dx;
00032 asm volatile("rdtsc\nmovl %%eax,%0\nmovl %%edx,%1":"=g"(ax),"=g"(dx): :"eax","edx");
00033 start_time =
00034 (static_cast<unsigned long long>(dx)<<32)
00035 + static_cast<unsigned long long>(ax);
00036 # else
00037 start_time = 0;
00038 # endif
00039 #else
00040 #ifdef NDEBUG
00041 getrusage(RUSAGE_SELF, &start_time);
00042 #else
00043 int ret=getrusage(RUSAGE_SELF, &start_time);
00044 assert(ret==0);
00045 #endif
00046 #endif
00047 }
00048 PerfMon() {
00049 restart();
00050 }
00051 unsigned long long stop(){
00052 #ifdef HAVE_TSC
00053 # ifndef _MSC_VER
00054 unsigned int ax,dx;
00055 asm volatile("rdtsc\nmovl %%eax,%0\nmovl %%edx,%1":"=g"(ax),"=g"(dx): :"eax","edx");
00056 const unsigned long long end_time
00057 = ((static_cast<unsigned long long>(dx)<<32)
00058 + static_cast<unsigned long long>(ax));
00059 return (end_time - PerfMon::start_time);
00060 # else
00061 return 0;
00062 # endif
00063 #else
00064 rusage end_time;
00065 #ifdef NDEBUG
00066 getrusage(RUSAGE_SELF,&end_time);
00067 #else
00068 int ret=getrusage(RUSAGE_SELF,&end_time);
00069 assert(ret==0);
00070 #endif
00071 return (end_time.ru_utime.tv_sec - start_time.ru_utime.tv_sec)*1000000
00072 +(end_time.ru_utime.tv_usec - start_time.ru_utime.tv_usec);
00073 #endif
00074 }
00075 void stop(const char *message,int loop){
00076 const unsigned long long cycles=stop();
00077 PerfMon::message(cycles, message, loop);
00078 }
00079 static void message(unsigned long long cycles,
00080 const char *message,long long int loop);
00081 };
00082
00083 class TSC
00084 {
00085 unsigned long long start_time;
00086 unsigned long long sum_time;
00087 long long int counter;
00088 std::string message;
00089 public:
00090 TSC(const char *m) :start_time(0ll),sum_time(0ll),counter(0ll),message(m) {}
00091 void start()
00092 {
00093 #ifdef HAVE_TSC
00094 # ifndef _MSC_VER
00095 unsigned int ax,dx;
00096 asm volatile("rdtsc\nmovl %%eax,%0\nmovl %%edx,%1":"=g"(ax),"=g"(dx): :"eax","edx");
00097 start_time =
00098 (static_cast<unsigned long long>(dx)<<32)
00099 + static_cast<unsigned long long>(ax);
00100 # else
00101 start_time = 0;
00102 # endif
00103 #endif
00104 counter++;
00105 }
00106 void stop(){
00107 #ifdef HAVE_TSC
00108 # ifndef _MSC_VER
00109 unsigned int ax,dx;
00110 asm volatile("rdtsc\nmovl %%eax,%0\nmovl %%edx,%1":"=g"(ax),"=g"(dx): :"eax","edx");
00111 const unsigned long long end_time
00112 = ((static_cast<unsigned long long>(dx)<<32)
00113 + static_cast<unsigned long long>(ax));
00114 sum_time+=end_time - start_time;
00115 # else
00116 sum_time = 0;
00117 # endif
00118 #endif
00119 }
00120 ~TSC()
00121 {
00122 PerfMon::message(sum_time,message.c_str(),counter);
00123 }
00124 };
00125 class Counter
00126 {
00127 unsigned long long int counter;
00128 std::string message;
00129 public:
00130 Counter(const char *m) :counter(0ll),message(m) {}
00131 Counter(std::string const& m) :counter(0ll),message(m) {}
00132 void count()
00133 {
00134 counter++;
00135 }
00136 ~Counter()
00137 {
00138 PerfMon::message(0ll,message.c_str(),counter);
00139 }
00140 };
00141 class CounterPair
00142 {
00143 unsigned long long int counter1;
00144 unsigned long long int counter2;
00145 std::string message;
00146 public:
00147 CounterPair(std::string const& m) :counter1(0ll),counter2(0ll),message(m) {}
00148 CounterPair(const char *file, const char *function, int line);
00149 void count1()
00150 {
00151 counter1++;
00152 }
00153 void count2()
00154 {
00155 counter2++;
00156 }
00157 ~CounterPair();
00158 };
00159 #ifndef _MSC_VER
00160 class MeasureTimeLock
00161 {
00162 timeval start;
00163 std::ostream& os;
00164 char const* message;
00165 public:
00166 MeasureTimeLock (std::ostream& os, char const* message)
00167 : os (os), message (message)
00168 {
00169 #ifndef NDEBUG
00170 int ret =
00171 #endif
00172 gettimeofday(&start, NULL);
00173 assert(ret == 0);
00174 }
00175
00176 ~MeasureTimeLock();
00177 };
00178 #endif
00179 }
00180 }
00181
00182
00183 #endif
00184
00185
00186
00187