我在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
专柜价值:6536266 262
专柜价值: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频率。
答案 0 :(得分:1)
QueryPerformanceCounter导致OAL内部的调用(BSP的一部分),其中系统中可用的最高分辨率渐进计数器应该用于返回64位值。 看起来像是特定BSP的问题。 在x86上,HW计时器的数量是有限的,可能是某些驱动程序正在使用QueryPerformanceCounter使用的计数器来使计时器的分辨率小于1ms。看起来该值被重置然后继续增加,这可能是由于驱动程序为自己设置了一个定时器(可能只使用定时器寄存器的低32位部分)。 如果你有BSP的源代码,你可以搜索OEMQueryPerformanceCounter实现,检查寄存器是否正在使用,并检查BSP的其他组件是否正在访问它们(或其他可能影响其操作性的寄存器)。
答案 1 :(得分:0)
专柜价值:6536266821
专柜价值:6536266 262
专柜价值:6536266 604
即使是第三次阅读也比第一次要小!但这里的相关性是什么?您应该使用QueryPerformanceFrequency()
读取性能计数器频率,以研究几百个计数的差异实际意味着什么。频率在MHz范围内,这仍然比毫秒好很多。您能否提供更长的QueryPerformanceCounter()
您还应该提供有关硬件的更多详细信息。性能计数器使用了什么资源? Acquiring high-resolution time stamps可以帮助您获得更详细的视图。
考虑到循环的线性行为,您可以绘制值与时间的关系图。这可能会使问题特别突出。它还可以允许建立拒绝/插值方案。