aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/timer
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@google.com>2014-07-16 19:59:32 -0400
committerGravatar Mike Klein <mtklein@google.com>2014-07-16 19:59:32 -0400
commit912947737a973421f4c58682b6171cb5ee00ad3a (patch)
tree87a3caef4916a894403f8d02edc0d64a9a945728 /tools/timer
parent7ef21622b2ed6b9c5fc4c149cb62944fc191f054 (diff)
Use __rdtsc on Windows.
This seems to be ~100x higher resolution than QueryPerformanceCounter. AFAIK, all our Windows perf bots have constant_tsc, so we can be a bit more direct about using rdtsc directly: it'll always tick at the max CPU frequency. Now, the question remains, what is the max CPU frequency to divide through by? It looks like QueryPerformanceFrequency actually gives the CPU frequency in kHz, suspiciously exactly what we need to divide through to get elapsed milliseconds. That was a freebie. I did some before/after comparison on slow benchmarks. Timings look the same. Going to land this without review tonight to see what happens on the bots; happy to review carefully tomorrow. R=mtklein@google.com TBR=bungeman BUG=skia: Review URL: https://codereview.chromium.org/394363003
Diffstat (limited to 'tools/timer')
-rw-r--r--tools/timer/SysTimer_windows.cpp35
-rw-r--r--tools/timer/SysTimer_windows.h2
2 files changed, 17 insertions, 20 deletions
diff --git a/tools/timer/SysTimer_windows.cpp b/tools/timer/SysTimer_windows.cpp
index 2f9d0a5d58..8e45b4a68e 100644
--- a/tools/timer/SysTimer_windows.cpp
+++ b/tools/timer/SysTimer_windows.cpp
@@ -6,6 +6,8 @@
*/
#include "SysTimer_windows.h"
+#include <intrin.h>
+
static ULONGLONG win_cpu_time() {
FILETIME createTime;
FILETIME exitTime;
@@ -23,11 +25,6 @@ static ULONGLONG win_cpu_time() {
return start_cpu_sys.QuadPart + start_cpu_usr.QuadPart;
}
-void SysTimer::startWall() {
- if (0 == ::QueryPerformanceCounter(&fStartWall)) {
- fStartWall.QuadPart = 0;
- }
-}
void SysTimer::startCpu() {
fStartCpu = win_cpu_time();
}
@@ -36,21 +33,21 @@ double SysTimer::endCpu() {
ULONGLONG end_cpu = win_cpu_time();
return static_cast<double>(end_cpu - fStartCpu) / 10000.0L;
}
+
+// On recent Intel chips (roughly, "has Core or Atom in its name") __rdtsc will always tick
+// at the CPU's maximum rate, even while power management clocks the CPU up and down.
+// That's great, because it makes measuring wall time super simple.
+
+void SysTimer::startWall() {
+ fStartWall = __rdtsc();
+}
+
double SysTimer::endWall() {
- LARGE_INTEGER end_wall;
- if (0 == ::QueryPerformanceCounter(&end_wall)) {
- end_wall.QuadPart = 0;
- }
+ unsigned __int64 end = __rdtsc();
- LARGE_INTEGER ticks_elapsed;
- ticks_elapsed.QuadPart = end_wall.QuadPart - fStartWall.QuadPart;
+ // This seems to, weirdly, give the CPU frequency in kHz. That's exactly what we want!
+ LARGE_INTEGER freq_khz;
+ QueryPerformanceFrequency(&freq_khz);
- LARGE_INTEGER frequency;
- if (0 == ::QueryPerformanceFrequency(&frequency)) {
- return 0.0L;
- } else {
- return static_cast<double>(ticks_elapsed.QuadPart)
- / static_cast<double>(frequency.QuadPart)
- * 1000.0L;
- }
+ return static_cast<double>(end - fStartWall) / static_cast<double>(freq_khz.QuadPart);
}
diff --git a/tools/timer/SysTimer_windows.h b/tools/timer/SysTimer_windows.h
index 62a9445134..380debd313 100644
--- a/tools/timer/SysTimer_windows.h
+++ b/tools/timer/SysTimer_windows.h
@@ -19,7 +19,7 @@ public:
double endWall();
private:
ULONGLONG fStartCpu;
- LARGE_INTEGER fStartWall;
+ unsigned __int64 fStartWall;
};
#endif