How to use QueryPerformanceCounter?

c++, timer, windows

Solution

#include <windows.h>

double PCFreq = 0.0;
__int64 CounterStart = 0;

void StartCounter()
{
    LARGE_INTEGER li;
    if(!QueryPerformanceFrequency(&li))
    cout << "QueryPerformanceFrequency failed!\n";

    PCFreq = double(li.QuadPart)/1000.0;

    QueryPerformanceCounter(&li);
    CounterStart = li.QuadPart;
}
double GetCounter()
{
    LARGE_INTEGER li;
    QueryPerformanceCounter(&li);
    return double(li.QuadPart-CounterStart)/PCFreq;
}

int main()
{
    StartCounter();
    Sleep(1000);
    cout << GetCounter() <<"\n";
    return 0;
}

This program should output a number close to 1000 (windows sleep isn't that accurate, but it should be like 999).

The `StartCounter()` function records the number of ticks the performance counter has in the `CounterStart` variable. The `GetCounter()` function returns the number of milliseconds since `StartCounter()` was last called as a double, so if `GetCounter()` returns 0.001 then it has been about 1 microsecond since `StartCounter()` was called.

If you want to have the timer use seconds instead then change

PCFreq = double(li.QuadPart)/1000.0;

to

PCFreq = double(li.QuadPart);

or if you want microseconds then use

PCFreq = double(li.QuadPart)/1000000.0;

But really it's about convenience since it returns a double.

Problem

I recently decided that I needed to change from using milliseconds to microseconds for my Timer class, and after some research I've decided that QueryPerformanceCounter is probably my safest bet. (The warning on `Boost::Posix` that it may not works on Win32 API put me off a bit). However, I'm not really sure how to implement it. What I'm doing is calling whatever `GetTicks()` esque function I'm using and assigning it to Timer's `startingTicks` variable. Then to find the amount of time passed I just subtract the function's return value from the `startingTicks`, and when I reset the timer I just call the function again and assign startingTicks to it. Unfortunately, from the code I've seen it isn't as simple as just calling `QueryPerformanceCounter()`, and I'm not sure what I'm supposed to pass as its argument.

Original source