CPU时钟频率因而QueryPerformanceCounter错了吗?

时间:2009-03-13 20:28:27

标签: timer

我正在使用QueryPerformanceCounter为一些代码计时。当代码开始报告时间明显错误时,我感到震惊。要将QPC的结果转换为“实际”时间,您需要除以QueryPerformanceFrequency返回的频率,因此经过的时间为:

时间=(QPC.end - QPC.start)/ QPF

重启后,QPF频率从2.7 GHz变为4.1 GHz。虽然使用QPC报告的时间确实发生了变化(下降了2.7 / 4.1),但我认为实际的硬件频率没有改变,因为正在运行的程序的挂钟时间没有变化。

MyComputer->属性显示:

英特尔(R) 奔腾(R) 4 CPU 2.80 GHz; 4.11 GHz; 1.99 GB的RAM;物理地址扩展

除此之外,系统似乎工作正常。

我会尝试重启以查看问题是否清除,但我担心这些关键性能计数器可能会在没有警告的情况下变为无效。

更新

虽然我很欣赏答案,尤其是链接,但我没有受影响的芯片组,也没有自己的CPU时钟。根据我的阅读,QPC和QPF基于PCI总线中的定时器,不受CPU时钟变化的影响。在我的情况下奇怪的是,QPF报告的频率变为不正确的值,并且在MyComputer中报告了这种变化的频率 - >我当然没有写的属性。

重新启动解决了我的问题(QPF现在报告了正确的频率),但我认为如果你打算使用QPC / QPF,你应该在信任它之前对另一个计时器进行验证。

5 个答案:

答案 0 :(得分:4)

显然在某些芯片组上有一个已知issue QPC,因此您可能需要确保没有这些芯片组。此外,一些双核AMD也可能导致problem。请参阅sebbbi的第二篇文章,他说:

  

QueryPerformanceCounter()和   QueryPerformanceFrequency()提供了一个   更好的分辨率,但有   不同的问题。例如在   Windows XP,所有AMD Athlon X2双   核心CPU返回任意一台的PC   核心“随机”(PC有时候   除非你,否则有点向后跳   特别安装AMD双核驱动程序   包来解决问题。我们没有   注意到任何其他双核心CPU   有类似的问题(p4双,p4 ht,   core2 dual,core2 quad,phenom quad)。

来自answer

答案 1 :(得分:1)

您应始终期望在支持SpeedStepCool'n'Quiet等技术的任何CPU上更改核心频率。壁挂时间不受影响,它使用RTC。您可能应该停止使用性能计数器,除非您可以容忍几个(5-50)毫秒的偶然相位调整,并且愿意执行一些数学计算以便通过连续或定期重新标准化来执行所述相位调整性能计数器值基于报告的性能计数器频率和RTC低分辨率时间(您可以按需执行此操作,也可以根据应用程序的最终需要从高分辨率计时器异步执行此操作。)

答案 2 :(得分:1)

您可以尝试使用.NET中的Stopwatch类,它可以帮助解决您的问题,因为它从所有这些低杠杆的东西中抽象出来。

使用IsHighResolution属性查看定时器是否基于高分辨率性能计数器。

  

注意:在多处理器计算机上,它   什么处理器并不重要   线程运行。但是,因为   BIOS或硬件中的错误   抽象层(HAL),你可以得到   不同的时间结果不同   处理器。指定处理器   对线程的亲和力,使用   ProcessThread .. ::。处理器亲和性   方法

答案 3 :(得分:0)

在黑暗中拍摄。

在我的家用电脑上,我曾经在BIOS中启用了“AI NOS”等功能。我怀疑这搞砸了QueryPerformanceCounter / QueryPerformanceFrequency API,因为尽管系统时钟以正常速率运行,并且普通应用程序运行得很好,但所有全屏3D游戏的运行速度都要快10-15%,例如,导致相邻的对话线在游戏中相互绊倒。

答案 4 :(得分:0)

当你使用QueryPerformance *时,我担心你不能说“我不应该有这个问题” - 而文档说明QueryPerformanceFrequency返回的值是不变的,实际的实验表明它确实不是'吨。

但是,每次打电话给QPC时,你也不想打电话给QPF。在实践中,我们发现周期性地(在我们的情况下每秒一次)调用QPF以获得新的值使得定时器保持足够好以进行可靠的分析。

正如已经指出的那样,您需要将所有QPC调用保留在单个处理器上以获得一致的结果。虽然这对于分析目的可能无关紧要(因为您可以使用ProcessorAffinity将线程锁定到单个CPU上),但您不希望对作为正确的多线程应用程序的一部分运行的计时执行此操作(因为那时)你冒着将一个硬工作线程锁定到忙碌的CPU的风险。

特别是不要随意锁定到CPU 0,因为你可以保证其他一些编码错误的应用程序也这样做了,然后两个应用程序都将在CPU 0上争用CPU时间而CPU 1(或2或3)坐在闲。随机选择可用的CPU集合,你至少有一个战斗机会,你没有锁定到过载的CPU。