00001 #include <limits>
00002 #include <map>
00003 #include <string>
00004
00010
00011 extern __inline__ unsigned long long int rdtsc()
00012 {
00013 unsigned long long int x;
00014 __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
00015 return x;
00016 }
00017
00018 class Timings;
00019
00021 class Timer {
00022 Timings &store;
00023 std::string name;
00024
00025 unsigned long long tStart;
00026
00027 public:
00029
00032 Timer(Timings &st, std::string n) : store(st), name(n) { start(); }
00033
00037 ~Timer();
00038
00042 void start();
00043
00047 void end();
00048 };
00049
00053 class Timings {
00057 struct Timing {
00058 int count;
00059 double sum;
00060 double min;
00061 double max;
00062
00063 Timing() : count(0), sum(0), min(std::numeric_limits<double>::max()), max(0) {}
00064 };
00065
00066 std::map<std::string, Timing > timings;
00067
00068 public:
00069 Timings() {}
00070
00074 void dumpTimings();
00075
00079 void addTiming(std::string name, unsigned long long int diff);
00080 };
00081
00082 inline void Timer::start()
00083 {
00084 tStart = rdtsc();
00085 }
00086
00087 inline void Timer::end()
00088 {
00089 unsigned long long tEnd = rdtsc();
00090
00091 store.addTiming(name, tEnd - tStart);
00092
00093 tStart = 0;
00094 }
00095
00096 inline Timer::~Timer()
00097 {
00098 if(tStart) {
00099 end();
00100 }
00101 }
00102
00103 inline void Timings::addTiming(std::string name, unsigned long long int diff)
00104 {
00105 Timing &last = timings[name];
00106 last.count ++;
00107 last.sum += diff/1e9;
00108 last.max = std::max(last.max, diff/1e9);
00109 last.min = std::min(last.min, diff/1e9);
00110 }
00111
00112 inline void Timings::dumpTimings()
00113 {
00114 std::cout << "Timings dump\n";
00115 std::cout << "\"Name\",\"Count\",\"Total (GCycles)\",\"Mean\",\"Min\",\"Max\"\n";
00116
00117 for(std::map<std::string, Timing >::const_iterator iter = timings.begin();
00118 iter != timings.end();
00119 iter++) {
00120 std::cout << '"' << iter->first
00121 << "\",\"" << iter->second.count
00122 << "\",\"" << iter->second.sum
00123 << "\",\"" << iter->second.sum/iter->second.count
00124 << "\",\"" << iter->second.min
00125 << "\",\"" << iter->second.max << "\"\n";
00126 }
00127 }