ctkHighPrecisionTimer.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*=============================================================================
  2. Library: CTK
  3. Copyright (c) German Cancer Research Center,
  4. Division of Medical and Biological Informatics
  5. Licensed under the Apache License, Version 2.0 (the "License");
  6. you may not use this file except in compliance with the License.
  7. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. =============================================================================*/
  15. #ifndef CTKHIGHPRECISIONTIMER_H
  16. #define CTKHIGHPRECISIONTIMER_H
  17. #include <qglobal.h>
  18. #ifdef Q_OS_UNIX
  19. #include <time.h>
  20. #include <unistd.h>
  21. #elif defined(Q_OS_WIN)
  22. #include <windows.h>
  23. #else
  24. #include <QTime>
  25. #endif
  26. #include "ctkException.h"
  27. /**
  28. * \ingroup Core
  29. *
  30. *
  31. * @brief A fast and high precision timer.
  32. *
  33. * This class provides a fast and high precision timer depending on
  34. * platform specific API. It can be used as a QTime replacement for
  35. * runtime measurements with a minimal performance overhead.
  36. */
  37. class ctkHighPrecisionTimer {
  38. public:
  39. inline ctkHighPrecisionTimer();
  40. inline void start();
  41. inline qint64 elapsedMilli();
  42. inline qint64 elapsedMicro();
  43. private:
  44. #ifdef _POSIX_MONOTONIC_CLOCK
  45. timespec startTime;
  46. #elif defined(Q_OS_WIN)
  47. LARGE_INTEGER timerFrequency;
  48. LARGE_INTEGER startTime;
  49. #else
  50. QTime startTime;
  51. #endif
  52. };
  53. #ifdef _POSIX_MONOTONIC_CLOCK
  54. inline ctkHighPrecisionTimer::ctkHighPrecisionTimer()
  55. {
  56. startTime.tv_nsec = 0;
  57. startTime.tv_sec = 0;
  58. }
  59. inline void ctkHighPrecisionTimer::start()
  60. {
  61. clock_gettime(CLOCK_MONOTONIC, &startTime);
  62. }
  63. inline qint64 ctkHighPrecisionTimer::elapsedMilli()
  64. {
  65. timespec current;
  66. clock_gettime(CLOCK_MONOTONIC, &current);
  67. return (static_cast<qint64>(current.tv_sec)*1000 + current.tv_nsec/1000/1000) -
  68. (static_cast<qint64>(startTime.tv_sec)*1000 + startTime.tv_nsec/1000/1000);
  69. }
  70. inline qint64 ctkHighPrecisionTimer::elapsedMicro()
  71. {
  72. timespec current;
  73. clock_gettime(CLOCK_MONOTONIC, &current);
  74. return (static_cast<qint64>(current.tv_sec)*1000*1000 + current.tv_nsec/1000) -
  75. (static_cast<qint64>(startTime.tv_sec)*1000*1000 + startTime.tv_nsec/1000);
  76. }
  77. #elif defined(Q_OS_WIN)
  78. inline ctkHighPrecisionTimer::ctkHighPrecisionTimer()
  79. {
  80. if (!QueryPerformanceFrequency(&timerFrequency))
  81. throw ctkRuntimeException("QueryPerformanceFrequency() failed");
  82. }
  83. inline void ctkHighPrecisionTimer::start()
  84. {
  85. //DWORD_PTR oldmask = SetThreadAffinityMask(GetCurrentThread(), 0);
  86. QueryPerformanceCounter(&startTime);
  87. //SetThreadAffinityMask(GetCurrentThread(), oldmask);
  88. }
  89. inline qint64 ctkHighPrecisionTimer::elapsedMilli()
  90. {
  91. LARGE_INTEGER current;
  92. QueryPerformanceCounter(&current);
  93. return (current.QuadPart - startTime.QuadPart) / (timerFrequency.QuadPart / 1000);
  94. }
  95. inline qint64 ctkHighPrecisionTimer::elapsedMicro()
  96. {
  97. LARGE_INTEGER current;
  98. QueryPerformanceCounter(&current);
  99. return (current.QuadPart - startTime.QuadPart) / (timerFrequency.QuadPart / (1000*1000));
  100. }
  101. #else
  102. inline ctkHighPrecisionTimer::ctkHighPrecisionTimer()
  103. : startTime(QTime::currentTime())
  104. {
  105. }
  106. inline void ctkHighPrecisionTimer::start()
  107. {
  108. startTime = QTime::currentTime();
  109. }
  110. inline qint64 ctkHighPrecisionTimer::elapsedMilli()
  111. {
  112. return startTime.elapsed();
  113. }
  114. inline qint64 ctkHighPrecisionTimer::elapsedMicro()
  115. {
  116. return startTime.elapsed() * 1000;
  117. }
  118. #endif
  119. #endif // CTKHIGHPRECISIONTIMER_H