How to Use Queryperformancecounter

How to use QueryPerformanceCounter?

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

How to use QueryPerformanceCounter to get results in seconds?

You need to get frequency and divide your 2 counters difference by it.

LARGE_INTEGER fr,t1,t2;

QueryPerformanceCounter(&t1);

// some lengthy code ...

QueryPerformanceCounter(&t2);

QueryPerformanceFrequency(&fr);

double diff_sec = (t2.QuadPart-t1.QuadPart)/(double)fr.QuadPart;

Python 2.x - QueryPerformanceCounter() on Windows

I've ported the C++ example you've given to Python using the ctypes module:

C++

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

QueryPerformanceFrequency(&Frequency);
QueryPerformanceCounter(&StartingTime);

// Activity to be timed

QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;

ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

Python

import ctypes
import ctypes.wintypes
import time

kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

starting_time = ctypes.wintypes.LARGE_INTEGER()
ending_time = ctypes.wintypes.LARGE_INTEGER()
elapsed_microseconds = ctypes.wintypes.LARGE_INTEGER()
frequency = ctypes.wintypes.LARGE_INTEGER()

kernel32.QueryPerformanceFrequency(ctypes.byref(frequency))
kernel32.QueryPerformanceCounter(ctypes.byref(starting_time))

# Activity to be timed, e.g.
time.sleep(2)

kernel32.QueryPerformanceCounter(ctypes.byref(ending_time))

elapsed_microseconds = ending_time.value - starting_time.value
elapsed_microseconds *= 1000000
elapsed_microseconds /= frequency.value

print(elapsed_microseconds)

I really appreciate the useful hints of @eryksun!

The code above should print something near to 2000000 (e.g. 2000248.7442040185, the value may be different from time to time). You may also use the round() or int() function to get rid of the decimals.

As @eryksun has commented you can also use time.clock(), which is implemented in C and also uses QueryPerformanceCounter().

Example doing exactly the same as the one using ctypes:

import time
starting_time = time.clock()

# Activity to be timed, e.g.
time.sleep(2)

ending_time = time.clock()

elapsed_microseconds = ending_time - starting_time
elapsed_microseconds *= 1000000

print(elapsed_microseconds)

Hope this helps!

Measuring time in C++ with high precision

The Stopwatch class in C# is based on these two Win32 API calls, which you can call from C/C++:

  • QueryPerformanceCounter
  • QueryPerformanceFrequency

Call the first function and divide it by the second function to get a value in seconds.

Example:

LARGE_INTEGER freq, start, end;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&start);
// do some long operation here
Sleep(5000);
QueryPerformanceCounter(&end);
// subtract before dividing to improve precision
double durationInSeconds = static_cast<double>(end.QuadPart - start.QuadPart) / freq.QuadPart;

Note that the following comment in the documentation is real, and should be considered. I'm personally observed this behavior in a VirtualBox virtual machine. Differences of dozens of milliseconds can exist between different processors, leading to unexpected results such as negative durations and longer-than-expected durations:

On a multiprocessor computer, it should not matter which processor is
called. However, you can get different results on different processors
due to bugs in the basic input/output system (BIOS) or the hardware
abstraction layer (HAL). To specify processor affinity for a thread,
use the SetThreadAffinityMask function.

You might be interested in this for more: System.Diagnostics.Stopwatch returns negative numbers in Elapsed... properties

Note that the Stopwatch class falls back on GetTickCount if the above two APIs aren't available or return failure codes. This is likely just to retain compatibility with Windows 9x; I've not encountered any issues myself with these APIs on modern PCs. GetTickCount won't have the precision you want, however.

Moving from C# to C++, QueryPerformanceCounter vs clock produce confusing results

clock() gives you the number of milliseconds since the program started. For example, the following program will print a number close to 500:

int main()
{
Sleep(500);
cout << clock() << endl;

/*
POSIX version:
std::cout << clock() * 1000.0 / CLOCKS_PER_SEC << std::endl;
CLOCKS_PER_SEC is 1000 in Windows
*/

return 0;
}

QueryPerformanceCounter is sort of similar to GetTickCount64, it is based on the time when the computer started. When you do Stop-Watch type subtraction, the results are very close. QueryPerformanceCounter is more accurate. chrono method from @BoPersson's link is also based on QueryPerformanceCounter.

MSDN recommends using QueryPerformanceCounter (QPC) for high resolution stamps:

Acquiring high-resolution time stamps

The same QPC function is used in managed code:

For managed code, the System.Diagnostics.Stopwatch class uses
QPC as its precise time basis

This function should have reasonable accuracy:

long long getmicroseconds()
{
LARGE_INTEGER fq, t;
QueryPerformanceFrequency(&fq);
QueryPerformanceCounter(&t);
return 1000000 * t.QuadPart / fq.QuadPart;
}

The computer clock is usually accurate to +/-1 second per day.

From above link:

Duration          Uncertainty
1 microsecond ± 10 picoseconds (10-12)
1 millisecond ± 10 nanoseconds (10-9)
1 second ± 10 microseconds
1 hour ± 60 microseconds
1 day ± 0.86 seconds
1 week ± 6.08 seconds

To simplify your other function, you can avoid double results. QuadPart is long long, so use that throughout the functions:

long long PCFreq = 0;
long long CounterStart = 0;
void StartCounter()
{
LARGE_INTEGER li;
QueryPerformanceFrequency(&li);
PCFreq = li.QuadPart;
QueryPerformanceCounter(&li);
CounterStart = li.QuadPart;
}

long long GetCounter()
{
if (PCFreq < 1) return 0;
LARGE_INTEGER li;
QueryPerformanceCounter(&li);

//for milliseconds: 1,000
return 1000 * (li.QuadPart - CounterStart) / PCFreq;

//for microseconds: 1,000,000
//return 1000000 * (li.QuadPart - CounterStart) / PCFreq;
}

How to get ticks from QueryPerformanceCounter in C#?

[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);

[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);

Taken from http://www.codeproject.com/Articles/2635/High-Performance-Timer-in-C

Old but it should still work

EDIT: The internals of StopWatch actually use QueryPerformanceCounter, so using the managed code should provide identical results, with better compatibility.

Time running backwards with QueryPerformanceCounter()

Counter Value: 6536266821

Counter Value: 6536266262

Counter Value: 6536266604

even the third read is smaller than the first! But what is the relevance here? You should read the performance counter frequency using QueryPerformanceFrequency() to investigate what a difference of a few hundred counts actually means. With a frequence in the MHz range this would still be much better than a millisecond. Can you provide a longer list of consecutive reads of QueryPerformanceCounter()

You should also provide more details about the hardware. What resource is used for the performance counter? Acquiring high-resolution time stamps may help you to get a more detailed view.

Considering a linear behavior of your loop you could do a plot of values vs. time. This may particularize the problem. It may also allow to establish a rejection/interpolation scheme.

How to calculate running time in C language

Include the <time.h> library and use the time_t time(time_t *timer); function.

Also, if you want to use QueryPerformanceCounter, then you need to include Winbase.h (and Windows.h).



Related Topics



Leave a reply



Submit