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