使用QueryPerformanceCounter()向后运行的时间

时间:2014-12-11 09:20:49

标签: c++ timer embedded windows-ce performancecounter

我在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频率。

2 个答案:

答案 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可以帮助您获得更详细的视图。

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