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