#ifndef timer_h #define timer_h #include class timer { public: timer(const char *name = 0); timer(const char *name, std::ostream &write_on_exit); ~timer(); void start(), stop(); void reset(); std::ostream &print(std::ostream &); double getTimeInSeconds(); private: void print_time(std::ostream &, const char *which, double time) const; union { long long total_time; struct { #if defined __PPC__ int high, low; #else int low, high; #endif }; }; unsigned long long count; const char *const name; std::ostream *const write_on_exit; static double CPU_speed_in_MHz, get_CPU_speed_in_MHz(); }; std::ostream &operator<<(std::ostream &, class timer &); inline void timer::reset() { total_time = 0; count = 0; } inline timer::timer(const char *name) : name(name), write_on_exit(0) { reset(); } inline timer::timer(const char *name, std::ostream &write_on_exit) : name(name), write_on_exit(&write_on_exit) { reset(); } inline timer::~timer() { if (write_on_exit != 0) print(*write_on_exit); } inline void timer::start() { #if (defined __PATHSCALE__) && (defined __i386 || defined __x86_64) unsigned eax, edx; asm volatile("rdtsc" : "=a"(eax), "=d"(edx)); total_time -= ((unsigned long long)edx << 32) + eax; #elif (defined __GNUC__ || defined __INTEL_COMPILER) && \ (defined __i386 || defined __x86_64) asm volatile("rdtsc\n\t" "subl %%eax, %0\n\t" "sbbl %%edx, %1" : "+m"(low), "+m"(high) : : "eax", "edx"); #else #error Compiler/Architecture not recognized #endif } inline void timer::stop() { #if (defined __PATHSCALE__) && (defined __i386 || defined __x86_64) unsigned eax, edx; asm volatile("rdtsc" : "=a"(eax), "=d"(edx)); total_time += ((unsigned long long)edx << 32) + eax; #elif (defined __GNUC__ || defined __INTEL_COMPILER) && \ (defined __i386 || defined __x86_64) asm volatile("rdtsc\n\t" "addl %%eax, %0\n\t" "adcl %%edx, %1" : "+m"(low), "+m"(high) : : "eax", "edx"); #endif ++count; } #endif