【问题标题】:Can someone decipher whether timeGetTime() or QueryPerformanceCounter/QueryPerformanceFrequency has lower overhead or/and accuracy?有人可以破译 timeGetTime() 或 QueryPerformanceCounter/QueryPerformanceFrequency 是否具有较低的开销或/和准确性?
【发布时间】:2011-03-25 09:08:01
【问题描述】:

这个想法是现有项目非常频繁地使用 timeGetTime()(对于 Windows 目标)。

milliseconds = timeGetTime();

现在,这可以替换为

double tmp = (double) lpPerformanceCount.QuadPart/ lpFrequency.QuadPart; 
milliseconds = rint(tmp * 1000);

lpPerformanceCount.QuadPart 和 lpFrequency.QuadPart 来自对 QueryPerformanceCounter() 和 QueryPerformanceFrequency() 的一次调用。

我知道 Windows 的内部结构有点像巫术,但有人可以破译这两者中的哪一个更准确或/并且有更多的开销吗?

我怀疑准确性可能相同,但 QueryPerformanceCounter 的开销可能会更少。但我没有确凿的数据来支持它。

如果情况正好相反,我当然不会感到惊讶。

如果开销很小,我会对准确性是否有任何差异更感兴趣。

【问题讨论】:

    标签: c# c++ c windows winapi


    【解决方案1】:

    timeGetTime() 的准确性是可变的,基于上次使用的 timeBeginPeriod。它永远不会超过一毫秒。 QueryPerformanceCounter 也是可变的,具体取决于硬件支持。它永远不会比大约一微秒更糟。

    它们都没有显着的开销,QPC 可能有点重。从您的问题中不清楚这对您是否重要。我对此表示怀疑,但要衡量。使用 QPC。

    【讨论】:

    • 如果将微秒转换为毫秒会更准确吗?
    • 嗯,这是一个非常深刻的问题。我会在那条路上走上正轨:是的。在常见的操作系统上,将代码执行时间精确到 微秒 级别是不可能给你一个准确的值的。最后 4 位数字只是噪音,当您一遍又一遍地重复计时测试时,它会不断变化。所以,是的,只是扔掉噪音数字会给你一个更稳定的数字。
    • 续:更稳定。但不是更准确。相对误差大致相同,以毫秒为单位的计时值要多一点。非常小。
    【解决方案2】:

    注意:QueryPerformanceCounter 可能取决于处理器。如果您的线程在一个 CPU 上抓取 perf 计数器,并在再次抓取之前在另一个 CPU 上结束,则结果可能不可靠。请参阅MSDN entry

    【讨论】:

    • 这似乎没有一个干净的解决方案,因为在通常情况下,在 1 个 CPU 上强制执行某些操作根本不利于性能。
    • 您链接到的 MSDN 条目说这只是有缺陷的 HAL 或 BIOS 的问题。有趣的是,“它有效,除非有错误”对于 timegetTime 也是如此。以及曾经编写的所有其他软件。
    • @jalf:不幸的是,有缺陷的 BIOS 相当普遍。
    • @Lela:问题在于性能计数器是低端供应商不一定会测试的东西,并且在生产软件中不会出现太多。因此,它们中的错误不会得到修复。尽你所能,但我避免在多核或 CPU 系统上使用性能计数器,除了调试(然后我很小心)。
    【解决方案3】:

    QPC 的准确性更高。 timeGetTime 精度在 1-10ms 范围内(其分辨率不低于 1ms),而 QPC 可以为您提供微秒范围内的精度。

    开销各不相同。 QPC 使用最好的硬件定时器。这可能是 CPU 中内置的一些轻量级的,或者它可能必须连接到主板上,这会增加显着的延迟。而且它可能会因为必须通过驱动程序来纠正计时器硬件的错误而变得更加昂贵。

    但两者都不是太昂贵。如果您不打算每秒调用数百万次计时器,那么开销对于两者来说都是微不足道的。

    【讨论】:

    • 但是换算成毫秒会更准确吗?
    • 也许吧。因为那样至少它会给你时间到最近的毫秒,这 timeGetTime 可能无法在所有系统上做。但是,如果您不需要精度,也不需要分辨率,并且您调用它的频率不足以使性能变得至关重要,您为什么要浪费时间担心使用哪个计时器?操作系统提供的每个计时器都足够好,您可以通过选择一个计时器为自己节省几个小时。
    【解决方案4】:

    我们更新了 QueryPerformanceCounter 的文档,这应该有助于回答上述问题。请看

    http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx

    埃德·布里格斯 微软公司

    【讨论】:

      【解决方案5】:

      QueryPerformanceCounter 不给你时间。为了转换它的值 进入时间度量,你必须使用 QueryPerformanceFrequency 这应该 让您知道计数器以哪个速率递增。但频率值更多或 少一个估计。计数器的频率会随着底层硬件和操作系统的版本而变化。但它不应被认为是一个常数。它有一个偏移,有时伴随着热漂移。 话虽如此,我建议谨慎使用QueryPerformanceCounter

      有些人仍然将accuracygranularity 混合在一起。 QueryPerformanceCounter 粒度更细, 而 timeGetTime 的准确性更高。

      但是,最快的源是GetSystemTimeAsFileTime,它返回一个以 100ns 为单位的时间值。但它的粒度不是 100ns。它的粒度取决于结果 timeGetDevCapstimeBeginPeriod 的设置。正确设置后者可以导致大约 10000 的粒度,这对应于大约 1ms。

      我已经写了更多细节here

      【讨论】:

        猜你喜欢
        • 2010-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-14
        相关资源
        最近更新 更多