3

This might seem like a really basic question but, When dividing the output of

QueryPerformanceCounter with QueryPerformanceFrequency, what is the resulting value in, i.e. seconds, milliseconds, microseconds?

I'm asking because I'm porting some code from Windows to Linux and I don't have a windows machine handy to experiment with. Some googling around provided no concrete answer for me.

Mysticial
  • 464,885
  • 45
  • 335
  • 332
hookenz
  • 36,432
  • 45
  • 177
  • 286

5 Answers5

7

We've updated the documentation for QueryPerformanceCounter, and the comparison between RDTSC and QueryPerformanceCounter accuracy above isn't quite right. For further information please see

http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx

Ed Briggs Microsoft Corporation

Ed Briggs
  • 229
  • 3
  • 2
5

Some googling around provided no concrete answer for me.

First Google search result for "QueryPerformanceCounter": the MSDN documentation for QueryPerformanceCounter()

Here's what it has to say:

Parameters

lpPerformanceCount [out]

Type: LARGE_INTEGER*

A pointer to a variable that receives the current performance-counter value, in counts.

First Google search result for "QueryPerformanceFrequency": the MSDN documentation for QueryPerformanceFrequency()

Here's what it has to say:

Parameters

lpFrequency [out]

Type: LARGE_INTEGER*

A pointer to a variable that receives the current performance-counter frequency, in counts per second. If the installed hardware does not support a high-resolution performance counter, this parameter can be zero.

The value obtained from QueryPerformanceCounter() is in counts. The value obtained from QueryPerformanceFrequency() is in counts per second. Using a bit of dimensional analysis:

(counts) / (counts/second) = seconds

Therefore, the result of dividing the two values is in seconds.

In silico
  • 51,091
  • 10
  • 150
  • 143
  • Thanks. I must have missed that part! – hookenz Jul 06 '12 at 02:08
  • This does not mean, however, that the resulting value of the divide is expressed in whole seconds. The high-performance counter allows you to implement counters with less than seconds precision. Say `QFF()` returns 100, you would be able to call `QFC()` and get a different value up to 100 times a second. – Remy Lebeau Jul 06 '12 at 02:16
  • It's the integer part I was curious about. – hookenz Jul 06 '12 at 02:28
  • Be-careful using counters if the counter is not counted you will have incorrect results!!! See my answer! – Jay Apr 12 '13 at 05:16
1

At least as far as I know, QPF typically depends on one of two sources. At least at one time, most single-processor systems used the processor's time-stamp counter register, accessed via the RDTSC instruction.

Multi-processor systems (and older systems that didn't have a TSC register) normally use the motherboard's on-board 1.024 MHz clock. On a multiprocessor/multicore system, the time-stamp counters of the processors/cores can be out of sync, so the time-stamp counter could give rather meaningless results (including negative time periods).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

Even though In silico answered the question, if you're looking for higher timer resolutions, you can use the rdtsc assembly instruction. rdtsc is about 1000x more accurate than QueryPerformanceCounter and QueryPerformanceFrequency as it uses the CPU clock (as opposed to the motherboard clock). The method would look something like so:

void QueryRDTSC(__int64* tick) {
 __asm {
  xor eax, eax
  cpuid
  rdtsc
  mov edi, dword ptr tick
  mov dword ptr [edi], eax
  mov dword ptr [edi+4], edx
 }
}

Fun fact: the slower motherboard clock is also more susceptible to clock drift due to the larger quartz crystal. Of course, whether or not you want to delve into the depths of high-resolution timing all depends on how important timing is in your application. Happy coding!

David Titarenco
  • 32,662
  • 13
  • 66
  • 111
  • 2
    Please read [Game Timing and Multicore Processors](http://msdn.microsoft.com/en-us/library/ee417693%28v=vs.85%29.aspx) which talks about `rdtsc`. – Jesse Good Jul 06 '12 at 02:24
  • Thanks, I'm using clock_gettime(CLOCK_MONOTONIC... ) for my purpose. – hookenz Jul 06 '12 at 02:29
  • I don't agree. The drivers that back QPF/QPC can use RDTSC just the same. On my machine, QPF returns 2.9 GHz, which is my CPU clock. QPC/QPF is just as effective but more portable than RDTSC, unless your system doesn't have drivers installed to use RDTSC as the QPC/QPF source. – antiduh Mar 11 '14 at 20:28
  • For anyone reading in the year 2022 and beyond: QueryPerformanceCounter can be a very expensive call on some machines/configurations - several microseconds, vs several nanoseconds for rdtsc - and often has a resolution of only 1MHz, so it's not suitable for very high-resolution or very frequent time sampling, as you'd need for profiling high-performance applications like games. Hence why serious profiling tools use rdtsc for instrumentation on Windows. QueryPerformanceCounter is the appropriate tool for something like frame pacing, but not for profiling. – Stuntddude May 29 '22 at 17:14
  • I should mention, the page @JesseGood linked is now very out of date - for example, it claims that rdtsc depends on clock frequency, which hasn't been true on any CPUs for a long time. – Stuntddude May 29 '22 at 17:16
0

Windows 7 has introduced a new way of generating results for QueryPerformanceCounter.

This function is assumed to be of finest possible granularity but its accuracy has to be looked at: The value returned by QueryPerformanceFrequency is neither exactly what is observed nor is it a constant. Particulary older systems suffer from severe thermal drift.

I have written some more details here.

Community
  • 1
  • 1
Arno
  • 4,994
  • 3
  • 39
  • 63