high_resolution_timer.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*=============================================================================
  2. Copyright (c) 2005-2007 Hartmut Kaiser
  3. 2007, 2009 Tim Blechmann
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #if !defined(BOOST_HIGH_RESOLUTION_TIMER_HPP)
  9. #define BOOST_HIGH_RESOLUTION_TIMER_HPP
  10. #include <boost/config.hpp>
  11. #include <boost/throw_exception.hpp>
  12. #if _POSIX_C_SOURCE >= 199309L
  13. #include "time.h"
  14. #include <stdexcept>
  15. #include <limits>
  16. namespace boost {
  17. class high_resolution_timer
  18. {
  19. public:
  20. high_resolution_timer()
  21. {
  22. restart();
  23. }
  24. void restart()
  25. {
  26. int status = clock_gettime(CLOCK_REALTIME, &start_time);
  27. if (status == -1)
  28. boost::throw_exception(std::runtime_error("Couldn't initialize start_time"));
  29. }
  30. double elapsed() const // return elapsed time in seconds
  31. {
  32. struct timespec now;
  33. int status = clock_gettime(CLOCK_REALTIME, &now);
  34. if (status == -1)
  35. boost::throw_exception(std::runtime_error("Couldn't get current time"));
  36. struct timespec diff;
  37. double ret_sec = double(now.tv_sec - start_time.tv_sec);
  38. double ret_nsec = double(now.tv_nsec - start_time.tv_nsec);
  39. while (ret_nsec < 0)
  40. {
  41. ret_sec -= 1.0;
  42. ret_nsec += 1e9;
  43. }
  44. double ret = ret_sec + ret_nsec / 1e9;
  45. return ret;
  46. }
  47. double elapsed_max() const // return estimated maximum value for elapsed()
  48. {
  49. return double((std::numeric_limits<double>::max)());
  50. }
  51. double elapsed_min() const // return minimum value for elapsed()
  52. {
  53. return 0.0;
  54. }
  55. private:
  56. struct timespec start_time;
  57. };
  58. } // namespace boost
  59. #elif defined(__APPLE__)
  60. #import <mach/mach_time.h>
  61. namespace boost {
  62. class high_resolution_timer
  63. {
  64. public:
  65. high_resolution_timer(void)
  66. {
  67. mach_timebase_info_data_t info;
  68. kern_return_t err = mach_timebase_info(&info);
  69. if (err)
  70. throw std::runtime_error("cannot create mach timebase info");
  71. conversion_factor = (double)info.numer/(double)info.denom;
  72. restart();
  73. }
  74. void restart()
  75. {
  76. start = mach_absolute_time();
  77. }
  78. double elapsed() const // return elapsed time in seconds
  79. {
  80. uint64_t now = mach_absolute_time();
  81. double duration = double(now - start) * conversion_factor;
  82. return duration
  83. }
  84. double elapsed_max() const // return estimated maximum value for elapsed()
  85. {
  86. return double((std::numeric_limits<double>::max)());
  87. }
  88. double elapsed_min() const // return minimum value for elapsed()
  89. {
  90. return 0.0;
  91. }
  92. private:
  93. uint64_t start;
  94. double conversion_factor;
  95. };
  96. } // namespace boost
  97. #elif defined(BOOST_WINDOWS)
  98. #include <stdexcept>
  99. #include <limits>
  100. #include <windows.h>
  101. namespace boost {
  102. ///////////////////////////////////////////////////////////////////////////////
  103. //
  104. // high_resolution_timer
  105. // A timer object measures elapsed time.
  106. // CAUTION: Windows only!
  107. //
  108. ///////////////////////////////////////////////////////////////////////////////
  109. class high_resolution_timer
  110. {
  111. public:
  112. high_resolution_timer()
  113. {
  114. start_time.QuadPart = 0;
  115. frequency.QuadPart = 0;
  116. if (!QueryPerformanceFrequency(&frequency))
  117. boost::throw_exception(std::runtime_error("Couldn't acquire frequency"));
  118. restart();
  119. }
  120. void restart()
  121. {
  122. if (!QueryPerformanceCounter(&start_time))
  123. boost::throw_exception(std::runtime_error("Couldn't initialize start_time"));
  124. }
  125. double elapsed() const // return elapsed time in seconds
  126. {
  127. LARGE_INTEGER now;
  128. if (!QueryPerformanceCounter(&now))
  129. boost::throw_exception(std::runtime_error("Couldn't get current time"));
  130. return double(now.QuadPart - start_time.QuadPart) / frequency.QuadPart;
  131. }
  132. double elapsed_max() const // return estimated maximum value for elapsed()
  133. {
  134. return (double((std::numeric_limits<LONGLONG>::max)())
  135. - double(start_time.QuadPart)) / double(frequency.QuadPart);
  136. }
  137. double elapsed_min() const // return minimum value for elapsed()
  138. {
  139. return 1.0 / frequency.QuadPart;
  140. }
  141. private:
  142. LARGE_INTEGER start_time;
  143. LARGE_INTEGER frequency;
  144. };
  145. } // namespace boost
  146. #else
  147. // For other platforms, simply fall back to boost::timer
  148. #include <boost/timer.hpp>
  149. #include <boost/throw_exception.hpp>
  150. namespace boost {
  151. typedef boost::timer high_resolution_timer;
  152. }
  153. #endif
  154. #endif // !defined(BOOST_HIGH_RESOLUTION_TIMER_HPP)