我正在研究在我们的系统中使用 QueryPerformanceCounter 的确切含义,并试图了解它对应用程序的影响。从我的 4 核单 CPU 机器上运行它可以看出,它需要大约 230ns 才能运行。当我在 24 核 4 cpu xeon 上运行它时,运行大约需要 1.4 毫秒。更有趣的是,在我的机器上以多个线程运行时它们不会相互影响。但是在多 CPU 机器上,线程会导致某种交互,从而导致它们相互阻塞。我想知道总线上是否有一些他们都查询的共享资源?当我调用 QueryPerformanceCounter 时究竟会发生什么,它真正衡量的是什么?
4 回答
Windows QueryPerformanceCounter() 具有确定处理器数量并在必要时调用同步逻辑的逻辑。它尝试使用 TSC 寄存器,但对于多处理器系统,该寄存器不能保证在处理器之间同步(更重要的是,由于智能降频和睡眠状态可能会有很大差异)。
MSDN 表示调用哪个处理器并不重要,因此您可能会看到针对这种情况的额外同步代码会导致开销。另请记住,它可以调用总线传输,因此您可能会看到总线争用延迟。
如果可能,请尝试使用 SetThreadAffinityMask() 将其绑定到特定处理器。否则,您可能只需要忍受延迟,或者您可以尝试不同的计时器(例如查看http://en.wikipedia.org/wiki/High_Precision_Event_Timer)。
我知道这个线程有点旧,但我想添加更多信息。首先,我同意 QueryPerformanceCounter 可能会在某些机器上花费更多时间,但我不确定 Ron 的回答是否一直是造成这种情况的原因。当我对这个问题进行一些研究时,我发现了一个关于如何实现 QueryPerformanceCounter 的各种网页。例如,Precision 不一样,accuracy告诉我,Windows,更具体的 HAL 会使用不同的计时设备来获取值。这意味着如果windows使用PIT等较慢的计时设备,将需要更多的时间来获取时间值。显然,使用 PIT 可能需要 PCI 事务,这是原因之一。
我还发现了另一篇文章:它是如何工作的:SQL Server 2008 R2 中的计时器输出 - 不变的 TSC 给出了类似的描述。事实上,这篇文章讲述了 SQLServer 如何以最佳方式为事务计时。
然后,我在 VMware 网站上找到了更多信息,因为我必须与使用 VM 的客户打交道,而且我发现使用 VM 进行时间测量还有其他问题。有兴趣的可以参考VMware论文——VMware Virtual Machines中的Timekeeping 这篇论文还讲了一些版本的windows是如何同步每个TSC的。因此,在某些情况下使用 QueryPerformanceCounter() 是安全的,我认为我们应该尝试类似 How It Works: Timer Outputs in SQL Server 2008 R2 建议找出调用 QueryPerformanceCounter() 时可能发生的情况
我的印象是在 x86 QueryPerformanceCounter() 上只是在幕后调用了 rdtsc。我很惊讶它在多核机器上的任何减速(我从未在我的 4 核 cpu 上注意到它)。
很久没这么用了,但如果有记忆的话,这个功能没有一个实现,因为各种硬件制造商都提供了胆量。
这是来自 MSDN 的一篇小文章:http: //msdn.microsoft.com/ja-jp/library/cc399059.aspx
此外,如果您要查询多个 CPU 的性能(而不是一个 CPU 上的多个内核),则必须通过总线进行通信,这既慢又可能是您看到一些阻塞的地方。
但是,就像我之前说的那样,已经有一段时间了。
麦克风