Timer.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <[email protected]>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. // High Resolution Timer.
  9. //
  10. // Resolution on Mac (clock tick)
  11. // Resolution on Linux (1 us not tested)
  12. // Resolution on Windows (clock tick not tested)
  13. #ifndef IGL_TIMER_H
  14. #define IGL_TIMER_H
  15. #ifdef WIN32 // Windows system specific
  16. #include <windows.h>
  17. #elif __APPLE__ // Unix based system specific
  18. #include <mach/mach_time.h> // for mach_absolute_time
  19. #else
  20. #include <sys/time.h>
  21. #endif
  22. #include <cstddef>
  23. #include <cstdint>
  24. namespace igl
  25. {
  26. /// Simple timer class
  27. class Timer
  28. {
  29. public:
  30. /// default constructor
  31. Timer():
  32. stopped(0),
  33. #ifdef WIN32
  34. frequency(),
  35. startCount(),
  36. endCount()
  37. #elif __APPLE__
  38. startCount(0),
  39. endCount(0)
  40. #else
  41. startCount(),
  42. endCount()
  43. #endif
  44. {
  45. #ifdef WIN32
  46. QueryPerformanceFrequency(&frequency);
  47. startCount.QuadPart = 0;
  48. endCount.QuadPart = 0;
  49. #elif __APPLE__
  50. startCount = 0;
  51. endCount = 0;
  52. #else
  53. startCount.tv_sec = startCount.tv_usec = 0;
  54. endCount.tv_sec = endCount.tv_usec = 0;
  55. #endif
  56. stopped = 0;
  57. }
  58. // default destructor
  59. ~Timer()
  60. {
  61. }
  62. #ifdef __APPLE__
  63. /// Raw mach_absolute_times going in, difference in seconds out
  64. /// @param[in] endTime end time
  65. /// @param[in] startTime start time
  66. /// @return time
  67. double subtractTimes( std::uint64_t endTime, std::uint64_t startTime )
  68. {
  69. std::uint64_t difference = endTime - startTime;
  70. static double conversion = 0.0;
  71. if( conversion == 0.0 )
  72. {
  73. mach_timebase_info_data_t info;
  74. kern_return_t err = mach_timebase_info( &info );
  75. //Convert the timebase into seconds
  76. if( err == 0 )
  77. conversion = 1e-9 * (double) info.numer / (double) info.denom;
  78. }
  79. return conversion * (double) difference;
  80. }
  81. #endif
  82. /// start timer
  83. void start()
  84. {
  85. stopped = 0; // reset stop flag
  86. #ifdef WIN32
  87. QueryPerformanceCounter(&startCount);
  88. #elif __APPLE__
  89. startCount = mach_absolute_time();
  90. #else
  91. gettimeofday(&startCount, NULL);
  92. #endif
  93. }
  94. /// stop the timer
  95. void stop()
  96. {
  97. stopped = 1; // set timer stopped flag
  98. #ifdef WIN32
  99. QueryPerformanceCounter(&endCount);
  100. #elif __APPLE__
  101. endCount = mach_absolute_time();
  102. #else
  103. gettimeofday(&endCount, NULL);
  104. #endif
  105. }
  106. /// get elapsed time in second
  107. /// @return time in seconds
  108. double getElapsedTime()
  109. {
  110. return this->getElapsedTimeInSec();
  111. }
  112. /// get elapsed time in second (same as getElapsedTime)
  113. /// @return time
  114. double getElapsedTimeInSec()
  115. {
  116. return this->getElapsedTimeInMicroSec() * 0.000001;
  117. }
  118. /// get elapsed time in milli-second
  119. /// @return time
  120. double getElapsedTimeInMilliSec()
  121. {
  122. return this->getElapsedTimeInMicroSec() * 0.001;
  123. }
  124. /// get elapsed time in micro-second
  125. /// @return time
  126. double getElapsedTimeInMicroSec()
  127. {
  128. double startTimeInMicroSec = 0;
  129. double endTimeInMicroSec = 0;
  130. #ifdef WIN32
  131. if(!stopped)
  132. QueryPerformanceCounter(&endCount);
  133. startTimeInMicroSec =
  134. startCount.QuadPart * (1000000.0 / frequency.QuadPart);
  135. endTimeInMicroSec = endCount.QuadPart * (1000000.0 / frequency.QuadPart);
  136. #elif __APPLE__
  137. if (!stopped)
  138. endCount = mach_absolute_time();
  139. return subtractTimes(endCount,startCount)/1e-6;
  140. #else
  141. if(!stopped)
  142. gettimeofday(&endCount, NULL);
  143. startTimeInMicroSec =
  144. (startCount.tv_sec * 1000000.0) + startCount.tv_usec;
  145. endTimeInMicroSec = (endCount.tv_sec * 1000000.0) + endCount.tv_usec;
  146. #endif
  147. return endTimeInMicroSec - startTimeInMicroSec;
  148. }
  149. private:
  150. // stop flag
  151. int stopped;
  152. #ifdef WIN32
  153. // ticks per second
  154. LARGE_INTEGER frequency;
  155. LARGE_INTEGER startCount;
  156. LARGE_INTEGER endCount;
  157. #elif __APPLE__
  158. std::uint64_t startCount;
  159. std::uint64_t endCount;
  160. #else
  161. timeval startCount;
  162. timeval endCount;
  163. #endif
  164. };
  165. }
  166. #endif // TIMER_H_DEF