1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 #include "SysTimer_windows.h" 8 9 #include <intrin.h> 10 11 static ULONGLONG win_cpu_time() { 12 FILETIME createTime; 13 FILETIME exitTime; 14 FILETIME usrTime; 15 FILETIME sysTime; 16 if (0 == GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &sysTime, &usrTime)) { 17 return 0; 18 } 19 ULARGE_INTEGER start_cpu_sys; 20 ULARGE_INTEGER start_cpu_usr; 21 start_cpu_sys.LowPart = sysTime.dwLowDateTime; 22 start_cpu_sys.HighPart = sysTime.dwHighDateTime; 23 start_cpu_usr.LowPart = usrTime.dwLowDateTime; 24 start_cpu_usr.HighPart = usrTime.dwHighDateTime; 25 return start_cpu_sys.QuadPart + start_cpu_usr.QuadPart; 26 } 27 28 void SysTimer::startCpu() { 29 fStartCpu = win_cpu_time(); 30 } 31 32 double SysTimer::endCpu() { 33 ULONGLONG end_cpu = win_cpu_time(); 34 return static_cast<double>(end_cpu - fStartCpu) / 10000.0L; 35 } 36 37 // On recent Intel chips (roughly, "has Core or Atom in its name") __rdtsc will always tick 38 // at the CPU's maximum rate, even while power management clocks the CPU up and down. 39 // That's great, because it makes measuring wall time super simple. 40 41 void SysTimer::startWall() { 42 fStartWall = __rdtsc(); 43 } 44 45 double SysTimer::endWall() { 46 unsigned __int64 end = __rdtsc(); 47 48 // This seems to, weirdly, give the CPU frequency in kHz. That's exactly what we want! 49 LARGE_INTEGER freq_khz; 50 QueryPerformanceFrequency(&freq_khz); 51 52 return static_cast<double>(end - fStartWall) / static_cast<double>(freq_khz.QuadPart); 53 } 54