High-Precision Timer

The Windows API provides the *QPC* API to acquire high-resolution time stamps or measure time intervals.

<aside> 💡 The API has a high resolution time stamp that fits the needs of a game (less than 1 microsecond).

</aside>

QPC stands for the [QueryPerformanceCounter](<https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter>) function that retrieves the current value of the performance counter.

BOOL QueryPerformanceCounter(
  LARGE_INTEGER *lpPerformanceCount
);

lpPerformanceCount is a pointer to a LARGE_INTEGER variable that receives the current value of the performance-counter as a 64-bit signed integer value.

The value is specified in ticks. To obtain the value in seconds, we need the frequency of the performance-counter.

[QueryPerformanceFrequency](<https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancefrequency>) retrieves the frequency of the performance counter.

<aside> 💡 The frequency is fixed and need only be queried during the application initialization.

</aside>

BOOL QueryPerformanceFrequency(
  LARGE_INTEGER *lpFrequency
);

lpFrequency is a pointer the LARGE_INTEGER variable that receives the frequency of the performance-counter, in ticks per second.

Based on the frequency and current value of the performance-counter, we can obtain a time in seconds.

$$ time = ticks / frequency $$

To obtain the elapsed time between two counters, we take the difference between the two values and divide by the frequency.

$$ elapsed time = (end - start) / frequency $$

Code

To get a value in:

LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);

LARGE_INTEGER startTime;
QueryPerformanceCounter(&startTime);

...

LARGE_INTEGER currentTime;
QueryPerformanceCounter(&endTime);

double elapsedTime = endTime.QuadPart - startTime.QuadPart;
elapsedTime /= (double)frequency.QuadPart;

double elapsedTimeInSeconds = elapsedTime * 1000.0;
double elapsedTimeInMilliseconds = elapsedTime * 1000000.0;