Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use QueryPerformanceCounter?

Tags:

c++

windows

timer

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.

like image 294
Anonymous Avatar asked Nov 15 '09 23:11

Anonymous


People also ask

What is QueryPerformanceCounter?

QueryPerformanceCounter() is used to get the current elapsed ticks, and QueryPerformanceFrequency() is used to get the number of ticks per second, which is used to convert ticks to the actual time. Here is a usage of QueryPerformanceCounter() for measuring elapsed time.

What is query performance frequency?

QueryPerformanceFrequency function (profileapi.Retrieves the frequency of the performance counter. The frequency of the performance counter is fixed at system boot and is consistent across all processors. Therefore, the frequency need only be queried upon application initialization, and the result can be cached.


1 Answers

#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.

like image 187
Ramónster Avatar answered Sep 21 '22 18:09

Ramónster