【问题标题】:What happens when QueryPerformanceCounter is called?调用 QueryPerformanceCounter 时会发生什么?
【发布时间】:2010-12-15 23:15:16
【问题描述】:

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

【问题讨论】:

  • omfg, 1.4ms !是的,现在这是一个很好的问题。根据这里:msdn.microsoft.com/en-us/library/windows/desktop/… 以 800ns 为例,这是一台表现不佳的机器。 1.4 毫秒会非常糟糕
  • 我在编写分析器时也被这个问题困扰。每次函数启动和返回时都会查询计时器。使用QueryPerformanceCounter 会减慢程序的爬行速度。使用GetTickCount 不会导致明显的减速,但它无法用于准确的分析......

标签: c++ windows winapi timing


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

    然后,我在 VMware 网站上找到了更多信息,因为我必须与使用 VM 的客户打交道,并且我发现使用 VM 进行时间测量还有其他问题。有兴趣的可以参考VMware论文——VMware Virtual Machines中的计时 在本文中,它还讨论了某些版本的 windows 如何同步每个 TSC。因此,在某些情况下使用 QueryPerformanceCounter() 是安全的,我认为我们应该尝试类似 How It Works: Timer Outputs in SQL Server 2008 R2 建议找出调用 QueryPerformanceCounter() 时可能发生的情况

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我不知道它在实践中是否有重大影响,除非您直接寻找它,否则可能无法衡量。在 4 核 cpu 上,无论如何都没有减速:)
      • @Goz 虽然对于旧的 Opterons 尤其如此,但较新的多核 CPU 已经同步了 TSC 寄存器。
      • @v.oddou:可能是真的……但时间戳计数器不是简单的循环计数吗?是否考虑节流?
      • @Goz 是的,我对这个问题有很多疑问。我唯一能合理想象的事情是在实践中发生的,那就是所有内核一起扩展速度。这反映在像“coretemp”或“CPUz”这样的程序中,它们只显示 1 个频率,但有 4 个温度和使用条。
      【解决方案4】:

      很久没这么用了,不过如果有记忆的话,这个功能没有一个实现,因为各个硬件制造商都提供了胆量。

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

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

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

      迈克

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-11
        • 2013-09-17
        • 2016-11-11
        • 1970-01-01
        相关资源
        最近更新 更多