timer.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #ifndef timer_h
  2. #define timer_h
  3. #include <iostream>
  4. class timer {
  5. public:
  6. timer(const char *name = 0);
  7. timer(const char *name, std::ostream &write_on_exit);
  8. ~timer();
  9. void start(), stop();
  10. void reset();
  11. std::ostream &print(std::ostream &);
  12. double getTimeInSeconds();
  13. private:
  14. void print_time(std::ostream &, const char *which, double time) const;
  15. union {
  16. long long total_time;
  17. struct {
  18. #if defined __PPC__
  19. int high, low;
  20. #else
  21. int low, high;
  22. #endif
  23. };
  24. };
  25. unsigned long long count;
  26. const char *const name;
  27. std::ostream *const write_on_exit;
  28. static double CPU_speed_in_MHz, get_CPU_speed_in_MHz();
  29. };
  30. std::ostream &operator << (std::ostream &, class timer &);
  31. inline void timer::reset()
  32. {
  33. total_time = 0;
  34. count = 0;
  35. }
  36. inline timer::timer(const char *name)
  37. :
  38. name(name),
  39. write_on_exit(0)
  40. {
  41. reset();
  42. }
  43. inline timer::timer(const char *name, std::ostream &write_on_exit)
  44. :
  45. name(name),
  46. write_on_exit(&write_on_exit)
  47. {
  48. reset();
  49. }
  50. inline timer::~timer()
  51. {
  52. if (write_on_exit != 0)
  53. print(*write_on_exit);
  54. }
  55. inline void timer::start()
  56. {
  57. #if (defined __PATHSCALE__) && (defined __i386 || defined __x86_64)
  58. unsigned eax, edx;
  59. asm volatile ("rdtsc" : "=a" (eax), "=d" (edx));
  60. total_time -= ((unsigned long long) edx << 32) + eax;
  61. #elif (defined __GNUC__ || defined __INTEL_COMPILER) && (defined __i386 || defined __x86_64)
  62. asm volatile
  63. (
  64. "rdtsc\n\t"
  65. "subl %%eax, %0\n\t"
  66. "sbbl %%edx, %1"
  67. :
  68. "+m" (low), "+m" (high)
  69. :
  70. :
  71. "eax", "edx"
  72. );
  73. #else
  74. #error Compiler/Architecture not recognized
  75. #endif
  76. }
  77. inline void timer::stop()
  78. {
  79. #if (defined __PATHSCALE__) && (defined __i386 || defined __x86_64)
  80. unsigned eax, edx;
  81. asm volatile ("rdtsc" : "=a" (eax), "=d" (edx));
  82. total_time += ((unsigned long long) edx << 32) + eax;
  83. #elif (defined __GNUC__ || defined __INTEL_COMPILER) && (defined __i386 || defined __x86_64)
  84. asm volatile
  85. (
  86. "rdtsc\n\t"
  87. "addl %%eax, %0\n\t"
  88. "adcl %%edx, %1"
  89. :
  90. "+m" (low), "+m" (high)
  91. :
  92. :
  93. "eax", "edx"
  94. );
  95. #endif
  96. ++ count;
  97. }
  98. #endif