c++ - 使用 HPET 时 QueryPerformanceFrequency 是否准确?

标签 c++ windows visual-c++ performancecounter

我正在研究 QueryPerformanceFrequency。 它过去常常返回 3.6 Mhz,但这对于我尝试做的事情来说还不够。

我已使用此命令启用 HPET bcdedit/set useplatformclock true。现在它返回 14.3 Mhz。太好了,它更精确......除了它不是。我很快意识到我没有达到预期的粒度。

如果我尝试轮询 QueryPerformanceCounter 直到它计时,我可以获得的最小增量是 11,这意味着 1.27Mhz。如果我尝试计算一秒钟内可以从 QueryPerformanceCounter 获得的不同值的数量,我得到 1.26Mhz

所以我想知道是否有一种方法可以真正充分利用 14.3 Mhz

我使用的是windows 7,64位系统,visual studio 2008。

最佳答案

众所周知,使用 HPET 硬件作为 QueryPerformanceCounter (QPC) 的来源会产生大量开销。

当配置了 HPET 时,QPC 是一个昂贵的调用。

它提供 14.3 MHz,这表明精度很高,但正如您所发现的,调用它的速度不够快,无法实际解析该频率。

因此,只要硬件能够这样做,Microsoft 就会将 CPU 的时间戳计数器 (TSC) 作为 QPC 的来源。 TSC 查询的开销要低得多。用于 QPC 的相关频率通常是 CPU 频率除以 1024;通常也为几 MHz。

QPC 在 TSC 模式下的调用非常快,以至于很多连续的调用可能会显示相同的结果(通常大约 20-30 次调用或 15 - 20 ns/调用)。 通过这种方式,您可以获得大约的典型分辨率。 0.3 us(在 3.4 GHz CPU 上)。

在切换到 HPET 之前,您观察到了 3.6 MHz。这可能是系统 ACPI PM 计时器 (3579545 Hz) 的签名,这表明您在切换到 HPET 之前没有在基于 TSC 的 QPC 上运行。

因此,无论哪种方式,运行 HPET 或 ACPI PM 计时器都会产生几 MHz 范围内的可用分辨率。两者都无法公开性能计数器频率 (PCF) 给出的完整分辨率,因为对 QPC 的调用过于昂贵。只有基于 TSC 的 QPC 足够快并且能够实际对 QPC 进行过采样。

Microsoft 最近刚刚发布了有关此事的更多详细信息:

参见 Acquiring high-resolution time stamps (MSDN 2014)了解详细信息。

这是一篇包含大量示例和详细说明的综合性文章。 QPC 用户必读。

...真正充分利用 14.3 Mhz 的方法?

不幸的是没有。

您可以从 Windows Sysinternals 运行 Coreinfo.exe 实用程序。 Sysinternals 已转移到 Microsoft technet。这是链接:Sysinternals System Information Utilities .这将为您提供以下问题的答案:如何检查我的系统是否具有非不变 TSC?

总结:最好的分辨率/精度/粒度是基于TSC的QPC得到的。

顺便说一句:作为QPC 资源的硬件的正确选择也会影响新GetSystemTimePreciseAsFileTime function 的通话费用。 (Windows 8 桌面版及更高版本)因为它在内部使用 QPC。

关于c++ - 使用 HPET 时 QueryPerformanceFrequency 是否准确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22942123/

相关文章:

C++ 获取错误 C2440

c++ - TRY/CATCH_ALL 与 try/catch

c++ - 声明多维数组时出现堆栈溢出异常

windows - MIT Kerberos 无法在 MSLSA 缓存中找到 TGT

c++ - 绘制错误的 CListCtrl 项

windows - QtCreator 无法打开包含文件 (Windows)

multithreading - VC++中终止线程

c++ - 多源 .cpp 文件问题

c++ - 指向指针的指针

c++ - 复制具有巨大数组成员的类时是否使用指针?