3

I'm trying to measure the CPU and Wall time for my program. The code should run on Windows so it's alright to use platform specific functions. For Wall time I use QueryPerformanceCounter() and it is precise. When I use GetProcessTimes() I get a 15.625 millisecond precision. On MSDN it says that the precision of the returned CPU time is 100 nanoseconds. Here is the code I am using:

void getCPUtime(unsigned long long *pUser, unsigned long long *pKernel) {
    FILETIME user, kernel, exit, start;
    ULARGE_INTEGER userCPU, kernelCPU;
    if (::GetProcessTimes(::GetCurrentProcess(), &start, &exit, &kernel, &user) != 0) {
        userCPU.LowPart = user.dwLowDateTime;
        userCPU.HighPart = user.dwHighDateTime;
        kernelCPU.LowPart = kernel.dwLowDateTime;
        kernelCPU.HighPart = kernel.dwHighDateTime;
    }
    *pUser = (unsigned long long)userCPU.QuadPart;
    *pKernel = (unsigned long long)kernelCPU.QuadPart;
}

And I am calling it from:

void someFunction() {
    unsigned long long *userStartCPU, *userEndCPU, *kernelStartCPU, *kernelEndCPU;
    double userCPUTime, kernelCPUTime;

    getCPUtime(userStartCPU, kernelStartCPU);

// Do stuff which takes longer than a millisecond

    getCPUtime(userEndCPU, kernelEndCPU);

    userCPUTime = (userEndCPU - userStartCPU) / (double)10000.00; // Convert to milliseconds
    kernelCPUTime = (kernelEndCPU - kernelStartCPU) / (double)10000.00; // Convert to milliseconds
}

Does anyone know why this is happening, or has any other way to precisely measure CPU time on Windows?

  • See this anwer http://stackoverflow.com/questions/1739259/how-to-use-queryperformancecounter – lsalamon Mar 28 '17 at 11:36
  • "On MSDN it says that the precision of the returned CPU time is 100 nanoseconds." No, it doesn't say that. It says the _resolution_ is 100 nanoseconds. That means the precision is _at best_ 100 nanoseconds, but that's just a lower bound as you discovered. – MSalters Mar 28 '17 at 12:40
  • @MSalters So it's due to my machine, or OS that I get this low precision? QueryPerformanceCounter is really precise though. – ZrtvenoJagnje Mar 28 '17 at 13:37
  • @Isalamon I need to measure CPU time, I am already using QueryPerformanceCounter for wall time. – ZrtvenoJagnje Mar 28 '17 at 13:41
  • I don't understand the downvotes on this question. Definitely want <15ms resolution, c.f. `clock_gettime(CLOCK_PROCESS_CPUTIME_ID ...)` on *nix. – TooTone Oct 17 '18 at 13:02

1 Answers1

1

MSDN has this page that outlines using a high resolution timer.

I would recommend looking at Google Benchmark]2. Looking at the Windows specific code, you might need to use double instead of integers as used in the MakeTime function here

CustodianSigma
  • 738
  • 9
  • 19
  • @crezfire I am using the QueryPerformanceCounter, but it measures wall time. I need to measure the CPU time, and on [GetProcessTimes](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683223(v=vs.85).aspx) it says that the precision is 100 nanoseconds. – ZrtvenoJagnje Mar 28 '17 at 09:20
  • @ZrtvenoJagnje Have updated the question to include code samples from Google Benchmark – CustodianSigma Mar 28 '17 at 10:55