【问题标题】:Why is there no boost::date_time with microsec resolution on Windows?为什么 Windows 上没有微秒分辨率的 boost::date_time?
【发布时间】:2014-05-03 15:49:17
【问题描述】:
在Win32 系统上boost::date_time::microsec_clock() 使用ftime 实现,它只提供毫秒分辨率:Link to doc
Stackoverflow 上有一些问题/答案说明了这一点并链接了文档,但没有解释为什么会这样:
似乎有一些方法可以在 Windows 上实现微秒级分辨率:
我感兴趣的是为什么 Boost 以这种方式实现它,而反过来可能有更合适的解决方案?
【问题讨论】:
-
在 boost 上有 this 票证,其中一条评论指出,“现在可以解决的分辨率是因为即使是 Windows 7 专业版也不管理或支持微秒级别的线程控制”。这可能是相关的,但我不确定(为什么我没有将其发布为明确的答案)。
标签:
c++
windows
boost
time
boost-date-time
【解决方案1】:
QueryPerformanceCounter 无法帮助您解决这个问题。它为您提供时间戳,但由于您不知道计数器何时开始,因此没有可靠的方法可以从中计算出绝对时间点。 boost::date_time 就是这样一个(用户可以理解的)时间点。
另一个区别是像 QueryPerformanceCounter 这样的计数器为您提供了一个稳定增加的计时器,而系统时间可能会受到用户的影响,因此可能会跳跃。
所以这两件事适用于不同的用例。一种用于表示实时,另一种用于在软件中获取精确时间并用于基准测试。
GetSystemTimePreciseAsFileTime 似乎符合高分辨率绝对时间的要求。我猜它没有被使用,因为它需要 Windows8。
【解决方案2】:
GetSystemTimePreciseAsFileTime 仅适用于 Windows 8 桌面应用程序。它模仿 Linux 的 GetTimeOfDay。该实现使用QueryPerformanceCounter 来实现微秒级分辨率。时间戳是在系统时间增量时获取的。对GetSystemTimePreciseAsFileTime 的后续调用将占用系统时间并添加经过的“性能计数器时间”(经过的滴答声/性能计数器频率)作为高分辨率部分。
QueryPerformanceCounter 的功能再次取决于平台特定的细节(HPET、ACPI PM 计时器、不变的 TSC 等)。有关详细信息,请参阅 MSDN: Acquiring high-resolution time stamps 和 SO: Is QueryPerformanceFrequency acurate when using HPET?。
各种版本的 Windows 确实有特定的方案来更新系统时间。 Windows XP 有一个固定的文件时间粒度,它独立于系统计时器分辨率。仅发布 Windows XP 版本允许通过更改系统计时器分辨率来修改系统时间粒度。
这可以通过多媒体定时器 API timeBeginPeriod 和/或隐藏 API NtSetTimerResolution 来完成(有关使用 ` 的更多详细信息,请参阅 this SO answer
timeBeginPeriod 和 NtSetTimerResolution)。
如上所述,GetSystemTimePreciseAsFileTime 仅适用于桌面应用程序。原因是需要特定的硬件。
我感兴趣的是为什么 Boost 以这种方式实现它,而反过来可能有更合适的解决方案?
考虑到上述事实将使实现变得非常复杂,结果非常特定于平台。每个 (!) Windows 版本都经历了时间保持的严重变化。即使是从 8 到 8.1 的最新小步骤,也大大改变了计时程序。但是,Windows 上的时间问题仍有进一步改进的空间。
我应该提一下,GetSystemTimePreciseAsFileTime 从 Windows 8.1 开始,给出的结果并不像预期的那样准确,也没有在MSDN: GetSystemTimePreciseAsFileTime function 中指定。它将系统文件时间与QueryPerformanceCounter 的结果相结合,以填补连续文件时间增量之间的空白,但不考虑系统时间调整。主动系统时间调整,例如由SetSystemTimeAdjustment完成,修改系统时间粒度和系统时间进度。但是,用于构建GetSystemTimePreciseAsFileTime 结果的性能计数器频率保持不变。结果,微秒部分被SetSystemTimeAdjustment设置的调整增益关闭。