00001 #include <limits> 00002 #include <map> 00003 #include <string> 00004 00006 00008 extern __inline__ unsigned long long int rdtsc() 00009 { 00010 unsigned long long int x; 00011 __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); 00012 return x; 00013 } 00014 00015 class Timings; 00016 00018 class Timer { 00019 Timings &store; 00020 std::string name; 00021 00022 unsigned long long tStart; 00023 00024 public: 00026 00029 Timer(Timings &st, std::string n) : store(st), name(n) { start(); } 00030 00034 ~Timer(); 00035 00039 void start(); 00040 00044 void end(); 00045 }; 00046 00050 class Timings { 00054 struct Timing { 00055 int count; 00056 double sum; 00057 double min; 00058 double max; 00059 00060 Timing() : count(0), sum(0), min(std::numeric_limits<double>::max()), max(0) {} 00061 }; 00062 00063 std::map<std::string, Timing > timings; 00064 00065 public: 00066 Timings() {} 00067 00071 void dumpTimings(); 00072 00076 void addTiming(std::string name, unsigned long long int diff); 00077 }; 00078 00079 inline void Timer::start() 00080 { 00081 tStart = rdtsc(); 00082 } 00083 00084 inline void Timer::end() 00085 { 00086 unsigned long long tEnd = rdtsc(); 00087 00088 store.addTiming(name, tEnd - tStart); 00089 00090 tStart = 0; 00091 } 00092 00093 inline Timer::~Timer() 00094 { 00095 if(tStart) { 00096 end(); 00097 } 00098 } 00099 00100 inline void Timings::addTiming(std::string name, unsigned long long int diff) 00101 { 00102 Timing &last = timings[name]; 00103 last.count ++; 00104 last.sum += diff/1e9; 00105 last.max = std::max(last.max, diff/1e9); 00106 last.min = std::min(last.min, diff/1e9); 00107 } 00108 00109 inline void Timings::dumpTimings() 00110 { 00111 std::cout << "Timings dump\n"; 00112 std::cout << "\"Name\",\"Count\",\"Total (GCycles)\",\"Mean\",\"Min\",\"Max\"\n"; 00113 00114 for(std::map<std::string, Timing >::const_iterator iter = timings.begin(); 00115 iter != timings.end(); 00116 iter++) { 00117 std::cout << '"' << iter->first 00118 << "\",\"" << iter->second.count 00119 << "\",\"" << iter->second.sum 00120 << "\",\"" << iter->second.sum/iter->second.count 00121 << "\",\"" << iter->second.min 00122 << "\",\"" << iter->second.max << "\"\n"; 00123 } 00124 }