perfmon.h
Go to the documentation of this file.
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   } // namespace misc
00180 } // namespace osl
00181 
00182 
00183 #endif /* MISC_PERFMON_H */
00184 // ;;; Local Variables:
00185 // ;;; mode:c++
00186 // ;;; c-basic-offset:2
00187 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines