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 }