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
Which Is Faster: Stack Allocation or Heap Allocation
Enum to String in Modern C++11/C++14/C++17 and Future C++20
Do I Need to Cast to Unsigned Char Before Calling Toupper(), Tolower(), Et Al.
Can Modern X86 Hardware Not Store a Single Byte to Memory
What Are All the Member-Functions Created by Compiler For a Class? Does That Happen All the Time
How to Track Down a "Double Free or Corruption" Error
How to Create an Std::Function from a Move-Capturing Lambda Expression
When Do I Use a Dot, Arrow, or Double Colon to Refer to Members of a Class in C++
How to Make a Simple C++ Makefile
Std::Unique_Ptr With an Incomplete Type Won't Compile
What Is the Correct Way of Using C++11'S Range-Based For
How to Properly Delete Nodes of Linked List in C++
Is (4 ≫ Y ≫ 1) a Valid Statement in C++? How to Evaluate It If So
How to Print Unicode Character in C++