时间使用 QueryPerformanceCounter() 向后运行

Time running backwards with QueryPerformanceCounter()

本文关键字:运行 QueryPerformanceCounter 时间      更新时间:2023-10-16

我在这篇文章中找到了有关使用QueryPerformanceCounter的有用信息,但我面临着一个我还没有找到答案的问题。

我正在为Windows CE 6.0开发一个应用程序,需要GetTickCount可以提供的更好的分辨率。这就是我选择QueryPerformanceCounter function的原因。

观察到我得到的计数器值来回走动。虽然它不是最终的应用程序,但这个小例子说明了这个问题:

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(中执行类型操作,并且在相同情况下发现负时间间隔。

我已经阅读(这里(使用多核平台时可以找到此问题。但是,情况并非如此,因为 Windows CE 6.0 不支持多核处理。

任何帮助找到发生这种情况的原因和/或避免此问题的任何解决方法将不胜感激。

[编辑]

我编辑问题以包含更多信息:

更长的连续读取列表(与上面的列表不同(:

计数器值:15234261579

计数器值:15234261594

计数器值:15234261609

计数器值:15234261624

计数器值:15234261640

计数器值:15234261064

计数器值:15234261079

计数器值:15234261094

计数器值:15234261109

计数器值:15234261125

计数器值:15234261140

计数器值:15234261155

计数器值:15234261170

计数器值:15234261185

计数器值:15234261201

计数器值:15234261216

计数器值:15234261231

计数器值:15234261246

关于硬件,正在使用英特尔赛扬 1047UE 处理器和 HM76 芯片组。

调用 QueryPerformanceFrequency 时,读取 1.19MHz 频率。

QueryPerformanceCounter 会导致 OAL(BSP 的一部分(内部的调用,其中应使用系统中可用的最高分辨率渐进计数器返回 64 位值。看起来该特定BSP存在问题。在 x86 上,硬件计时器的数量是有限的,可能是某些驱动程序正在使用 QueryPerformanceCounter 使用的计数器来拥有分辨率小于 1 毫秒的计时器。似乎该值被重新设置然后继续增加,这可能是由于驱动程序为自己设置了一个计时器(可能只使用计时器寄存器的较低 32 位部分(。如果你有BSP的源代码,你可以搜索OEMQueryPerformanceCounter实现,检查寄存器是否正在使用,并检查BSP的其他组件是否正在访问它们(或其他可能影响其操作性的寄存器(。

计数器值:6536266821

计数器值:6536266262

计数器值:6536266 604

甚至第三次阅读也比第一次小!但是这里有什么相关性?您应该使用 QueryPerformanceFrequency() 读取性能计数器频率,以调查几百个计数的差异实际上意味着什么。在MHz范围内的频率下,这仍然比一毫秒好得多。您能否提供更长的连续读取QueryPerformanceCounter()列表

您还应该提供有关硬件的更多详细信息。性能计数器使用什么资源?获取高分辨率时间戳可以帮助您获得更详细的视图。

考虑到循环的线性行为,您可以绘制值与时间的关系图。这可能会使问题具体化。它还可以允许建立拒绝/插值方案。