我在 this post 中找到了有关使用 QueryPerformanceCounter 的有用信息但我面临一个我还没有找到答案的问题。
我正在为 Windows CE 6.0 开发一个应用程序,需要 GetTickCount 可以提供的更好的分辨率。这就是我选择 QueryPerformanceCounter 函数的原因。
我观察到我得到的计数器值来回变化。虽然这不是最终的应用程序,但这个小例子说明了问题:
int i;
BOOL bRet;
LARGE_INTEGER liCounter;
for ( i = 0; i < 100; i++)
{
bRet = QueryPerformanceCounter(&liCounter);
if(bRet)
{
printf("Counter Value: %llu \n", liCounter.QuadPart);
}
}
它打印一系列 100 个计数器值,这些值预计是递增的。然而,有一些计数器值相对于先前的值递减。例如:
...
计数器值:6536266821
计数器值:6536266262
计数器值:6536266604
...
此行为是有问题的,因为在最终应用程序 (endCounterValue-startCoutnerValue) 中执行了类型操作,并且在相同情况下发现了负时间间隔。
我已阅读 ( here ) 使用多核平台时会发现此问题。然而,情况并非如此,因为 Windows CE 6.0 不支持多核处理。
如果您能帮助找出发生这种情况的原因和/或避免此问题的任何解决方法,我们将不胜感激。
[编辑]
我编辑问题以包含更多信息:
更长的连续读取列表(与上面的列表不同):
计数器值:15234261579
计数器值:15234261594
计数器值:15234261609
计数器值:15234261624
计数器值:15234261640
计数器值:15234261064
计数器值:15234261079
计数器值:15234261094
计数器值:15234261109
计数器值:15234261125
计数器值:15234261140
计数器值:15234261155
计数器值:15234261170
计数器值:15234261185
计数器值:15234261201
计数器值:15234261216
计数器值:15234261231
计数器值:15234261246
在硬件方面,使用了 Intel Celeron 1047UE 处理器和 HM76 芯片组。
调用 QueryPerformanceFrequency 时,读取 1.19MHz 频率。
最佳答案
QueryPerformanceCounter 导致 OAL(BSP 的一部分)内部的调用,其中系统中可用的最高分辨率累进计数器应该用于返回 64 位值。 看起来像是那个特定 BSP 的问题。 在 x86 上,硬件计时器的数量是有限的,并且可能是某些驱动程序正在使用 QueryPerformanceCounter 使用的计数器来使计时器的分辨率小于 1ms。看起来这个值被重新设置然后继续增加,这可能是由于驱动程序为自己设置了一个定时器(可能只使用定时器寄存器的低 32 位部分)。 如果您有 BSP 的源代码,您可以搜索 OEMQueryPerformanceCounter 实现,检查正在使用的寄存器并检查 BSP 的其他组件是否正在访问它们(或可能影响其操作性的其他寄存器)。
关于c++ - 使用 QueryPerformanceCounter() 倒计时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27419223/