Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CPU clock frequency and thus QueryPerformanceCounter wrong?

Tags:

timer

I am using QueryPerformanceCounter to time some code. I was shocked when the code starting reporting times that were clearly wrong. To convert the results of QPC into "real" time you need to divide by the frequency returned from QueryPerformanceFrequency, so the elapsed time is:

Time = (QPC.end - QPC.start)/QPF

After a reboot, the QPF frequency changed from 2.7 GHz to 4.1 GHz. I do not think that the actual hardware frequency changed as the wall clock time of the running program did not change although the time reported using QPC did change (it dropped by 2.7/4.1).

MyComputer->Properties shows:

Intel(R) Pentium(R) 4 CPU 2.80 GHz; 4.11 GHz; 1.99 GB of RAM; Physical Address Extension

Other than this, the system seems to be working fine.

I will try a reboot to see if the problem clears, but I am concerned that these critical performance counters could become invalid without warning.

Update:

While I appreciate the answers and especially the links, I do not have one of the affected chipsets nor to I have a CPU clock that varies itself. From what I have read, QPC and QPF are based on a timer in the PCI bus and not affected by changes in the CPU clock. The strange thing in my situation is that the FREQUENCY reported by QPF changed to an incorrect value and this changed frequency was also reported in MyComputer -> Properties which I certainly did not write.

A reboot fixed my problem (QPF now reports the correct frequency) but I assume that if you are planning on using QPC/QPF you should validate it against another timer before trusting it.

like image 345
NormD Avatar asked Mar 13 '09 20:03

NormD


3 Answers

Apparently there is a known issue with QPC on some chipsets, so you may want to make sure you do not have those chipset. Additionally some dual core AMDs may also cause a problem. See the second post by sebbbi, where he states:

QueryPerformanceCounter() and QueryPerformanceFrequency() offer a bit better resolution, but have different issues. For example in Windows XP, all AMD Athlon X2 dual core CPUs return the PC of either of the cores "randomly" (the PC sometimes jumps a bit backwards), unless you specially install AMD dual core driver package to fix the issue. We haven't noticed any other dual+ core CPUs having similar issues (p4 dual, p4 ht, core2 dual, core2 quad, phenom quad).

From this answer.

like image 176
grieve Avatar answered Sep 24 '22 14:09

grieve


You should always expect the core frequency to change on any CPU that supports technology such as SpeedStep or Cool'n'Quiet. Wall time is not affected, it uses a RTC. You should probably stop using the performance counters, unless you can tolerate a few (5-50) millisecond's worth of occasional phase adjustments, and are willing to perform some math in order to perform the said phase adjustment by continuously or periodically re-normalizing your performance counter values based on the reported performance counter frequency and on RTC low-resolution time (you can do this on-demand, or asynchronously from a high-resolution timer, depending on your application's ultimate needs.)

like image 26
vladr Avatar answered Sep 21 '22 14:09

vladr


You can try to use the Stopwatch class from .NET, it could help with your problem since it abstracts from all this low-lever stuff.

Use the IsHighResolution property to see whether the timer is based on a high-resolution performance counter.

Note: On a multiprocessor computer, it does not matter which processor the thread runs on. However, because of bugs in the BIOS or the Hardware Abstraction Layer (HAL), you can get different timing results on different processors. To specify processor affinity for a thread, use the ProcessThread..::.ProcessorAffinity method.

like image 29
compie Avatar answered Sep 22 '22 14:09

compie