调用QueryPerformanceCounter时会发生什么?

时间:2009-11-12 16:45:00

标签: c++ windows winapi timing

我正在研究在我们的系统中使用QueryPerformanceCounter的确切含义,并试图了解它对应用程序的影响。我可以看到在我的4核单CPU机器上运行它需要大约230ns才能运行。当我在24核4 cpu xeon上运行它需要大约1.4ms才能运行。更有趣的是,在我的机器上运行多个线程时,它们不会相互影响。但是在多CPU机器上,线程会导致某种交互,导致它们相互阻塞。 我想知道他们都在查询总线上是否有一些共享资源?当我调用QueryPerformanceCounter时它究竟发生了什么?它真正测量了什么?

4 个答案:

答案 0 :(得分:10)

Windows QueryPerformanceCounter()具有确定处理器数量的逻辑,并在必要时调用同步逻辑。它试图使用TSC寄存器,但对于多处理器系统,不能保证该寄存器在处理器之间同步(更重要的是,由于智能的低频和睡眠状态,它可能会有很大差异)。

MSDN表示调用哪个处理器并不重要,因此您可能会看到额外的同步代码,因为这种情况会导致开销。还要记住,它可以调用总线传输,因此您可能会看到总线争用延迟。

如果可能,尝试使用SetThreadAffinityMask()将其绑定到特定处理器。否则你可能只是忍受延迟,或者你可以尝试不同的计时器(例如看看http://en.wikipedia.org/wiki/High_Precision_Event_Timer)。

答案 1 :(得分:4)

我知道这个帖子有点旧,但我想添加更多信息。 首先,我确实同意QueryPerformanceCounter可以在某些机器上花费更多时间,但我不确定Ron的答案是否一直是这样的原因。 当我在这个问题上做一些研究时,我发现了一个讨论QueryPerformanceCounter如何实现的各种网页。 例如,Precision is not the same as accuracy告诉我,更具体的Windows,HAL将使用不同的计时设备来获取值。这意味着如果Windows使用较慢的计时设备(如PIT),则需要更多时间来获取时间值。显然,使用PIT可能需要PCI事务,这是一个原因。

我还发现了另一篇文章:工作原理:SQL Server 2008 R2中的计时器输出 - 不变TSC给出了类似的描述。实际上,本文讲述了SQLServer如何以最佳方式为事务计时。

然后,我在VMware网站上找到了更多信息,因为我不得不与使用虚拟机的客户打交道,我发现虚拟机的时间测量存在其他问题。有兴趣的人请参阅VMware论文 - VMware虚拟机中的计时 在本文中,它还讨论了某些版本的Windows如何同步每个TSC。因此,在某些情况下使用QueryPerformanceCounter()是安全的,我认为我们应该尝试使用它的工作原理:SQL Server 2008 R2中的计时器输出建议查找调用QueryPerformanceCounter()时可能发生的事情

答案 2 :(得分:3)

我的印象是在x86 QueryPerformanceCounter()上只调用了rdtsc。我很惊讶它在多核机器上有任何减速(我从来没有在我的4核CPU上注意到它。)

答案 3 :(得分:2)

自从我使用这么长时间以来已经很长时间了,但是如果内存服务的话,这个功能没有一个实现,因为胆量是由各种硬件制造商提供的。

以下是MSDN的一篇小文章: http://msdn.microsoft.com/ja-jp/library/cc399059.aspx

此外,如果您要查询多个CPU的性能(而不是一个CPU上的多个内核),那么它将不得不通过总线进行通信,这既慢又可能是您看到阻塞的地方。

但是,就像我之前说的那样,已经有一段时间了。

麦克