在Win32
系统上,boost::date_time::microsec_clock()
使用ftime
实现,该系统仅提供毫秒分辨率:链接到文档
Stackoverflow上有一些问题/答案,说明了这一点并链接了文档,但没有解释为什么会出现这种情况:
- 堆栈溢出#1
- 堆栈溢出#2
似乎有一些方法可以在Windows上实现微秒分辨率:
- GetSystemTimePreciseAsFileTime(Win8++(
- 查询性能计数器
我感兴趣的是,为什么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确实有特定的方案来更新系统时间。WindowsXP有一个固定的文件时间粒度,它独立于系统计时器的分辨率。只有Windows XP之后的版本才允许通过更改系统计时器分辨率来修改系统时间粒度。
这可以通过多媒体定时器API timeBeginPeriod
和/或隐藏的API NtSetTimerResolution
来实现(有关使用`timeBeginPeriod和NtSetTimerResolution(。
如上所述,GetSystemTimePreciseAsFileTime
仅适用于桌面应用程序。原因是需要特定的硬件。
我感兴趣的是,为什么Boost以这种方式实现它,而反过来又可能有更合适的解决方案
接受上述事实将使实现变得非常复杂,结果也非常具体每个(!(Windows版本都经历了严格的计时更改。即使是从8到8.1的最新一小步,也大大改变了计时程序。但是,在Windows上仍然有进一步改进时间问题的空间。
我应该指出的是,从Windows 8.1开始,GetSystemTimePreciseAsFileTime
并没有给出预期或MSDN中指定的准确结果:GetSystemTimePreciseAsFileTime函数。它将系统文件时间与QueryPerformanceCounter
的结果相结合,以填补连续文件时间增量之间的间隙,但不考虑系统时间调整。主动系统时间调整,例如由SetSystemTimeAdjustment
完成,修改系统时间粒度和系统时间的进度。然而,用于构建GetSystemTimePreciseAsFileTime
的结果的所使用的性能计数器频率保持恒定。结果,微秒部分被SetSystemTimeAdjustment
设置的调整增益关闭。