我正在研究在我们的系统中使用QueryPerformanceCounter的确切含义,并试图了解它对应用程序的影响。 我可以看到在我的4核单CPU机器上运行它需要大约230ns运行。 当我运行在24核心4 CPU的Xeon它需要大约1.4ms运行。 在我的机器上运行multithreading时更有趣,它们不会互相影响。 但是在多CPU机器上,线程会导致某种交互,导致它们互相阻塞。 我想知道是否有总线上的一些共享资源,他们都查询? 当我调用QueryPerformanceCounter时究竟发生了什么,它真正衡量的是什么?
Windows QueryPerformanceCounter()具有确定处理器数量的逻辑,并在必要时调用同步逻辑。 它试图使用TSC寄存器,但是对于多处理器系统,这个寄存器不能保证在处理器之间同步(更重要的是,由于智能降频和睡眠状态,这个寄存器可能会有很大的差别)。
MSDN表示,这是调用哪个处理器并不重要,所以你可能会看到额外的syncronization代码,这种情况会导致开销。 另外请记住,它可以调用巴士转移,所以你可能会看到巴士争用延误。
如果可能,尝试使用SetThreadAffinityMask()将其绑定到特定的处理器。 否则,你可能只需要忍受延迟,或者你可以尝试一个不同的计时器(例如看看http://en.wikipedia.org/wiki/High_Precision_Event_Timer )。
我知道这个线程有点老,但我想添加更多的信息。 首先,我同意QueryPerformanceCounter可以在某些机器上花费更多的时间,但是我不确定Ron的答案是否一直是这个原因。 当我在这个问题上做了一些研究时,我发现了一个关于如何实现QueryPerformanceCounter的各种网页。 比如Precision的精确度不一样,告诉我Windows,HAL更具体的会用不同的计时器来获得价值。 这意味着如果Windows使用较慢的计时设备(如PIT),则需要更多的时间来获取时间值。 很明显,使用PIT可能需要PCI事务,所以这将是一个原因。
我还发现了另一篇文章:它是如何工作的:SQL server 2008 R2中的计时器输出 – 不变的TSC给出了类似的描述。 实际上,这篇文章讲述了SQLserver如何以最好的方式来处理事务。
然后,我在VMware网站上找到了更多的信息,因为我不得不面对正在使用虚拟机的客户,而且我发现虚拟机的时间测量还存在其他问题。 对于那些有兴趣的人,请参阅VMware论文 – VMware虚拟机中的计时在本文中,它还讨论了一些版本的Windows如何同步每个TSC。 因此,在某些情况下使用QueryPerformanceCounter()是安全的,我认为我们应该尝试类似于SQL server 2008 R2中的定时器输出的方法,以便在查询QueryPerformanceCounter()时发现可能发生的情况。
我的印象是,在x86 QueryPerformanceCounter()的封面下只是调用了rdtsc。 我很惊讶,它在多核心机器上有任何放缓(我从来没有注意到它在我的4核心CPU上)。
我用了这么长时间已经很久了,但是如果内存服务的话,这个函数没有一个实现,因为各个硬件厂商都提供这个内存。
这是来自MSDN的一篇小文章: http : //msdn.microsoft.com/ja-jp/library/cc399059.aspx
另外,如果你在多个CPU上查询性能(而不是在一个CPU上的多个内核),它将不得不在整个总线上进行通信,这是较慢的,可能是你看到一些阻塞的地方。
不过,就像我之前说的那样,已经有一段时间了。
麦克风