如何在Windows平台上使用C ++ 实现长期高分辨率计时?

5
我需要在长时间(几个小时)内每隔几毫秒(20、30、40ms)获取精确的时间戳。时间戳所在的函数是由第三方库作为回调调用的。
使用GetSystemTime()可以获得正确的系统时间戳,但只能精确到毫秒,这对我来说不够精确。使用QueryPerformanceTimer()可以获得更精确的时间戳,但在长时间内与系统时间戳不同步(参见http://msdn.microsoft.com/en-us/magazine/cc163996.aspx)。
上面链接提供的解决方案似乎只适用于旧计算机,在我尝试在新计算机上使用它时会出现同步卡住的问题。
对我来说,Boost似乎也只能以毫秒为单位工作。如果可能的话,我想避免使用外部库,但如果没有其他选择,我会使用它。
有什么建议吗?

实际上,GetSystemTime() 函数的分辨率为1毫秒,但精度只有15毫秒。 - user172783
@lttlrck 你可以使用 timeBeginPeriod() 来提高准确性。 - fdlm
旧问题,带有过时的答案。现在你应该使用 std::chrono 来完成这样的任务。 - davidhigh
4个回答

4

这篇文章已经被CodeProject删除,但这似乎是一份副本:DateTimePrecise C#类。其想法是使用QueryPerformanceCounter API来获得准确的小增量,并定期进行调整以保持长期精度。这可以提供大约微秒级别的精度(“大约”是因为它仍然不是完全精确的,但仍然相当可用)。

另请参阅:Windows上微秒分辨率时间戳


0

你使用的是哪种语言?

  • 在Java(1.5或以上版本)中,我建议使用“System.nanoTime()”,它不需要导入任何内容。

请记住,在Windows中,时间片粒度为1000ms / 64 = 15.625ms。

  • 这将影响进程间通信,特别是在单处理器机器上或同时运行几个重CPU使用进程的机器上。

  • 事实上,我刚刚通过eBay获得了DOS 6.22和Windows for Workgroups 3.11/3.15,因此我可以截屏显示我开始接触它时的单处理器Windows机器的原始时间片配置。(虽然在3.0以上的版本中可能看不到)。


我正在使用C++ - 我会将这个添加到问题的标题中。但还是谢谢你的回答。 - fdlm

0

在Windows上,你很难找到比QueryPerformanceTimer()更好的东西。

在现代硬件上,它使用HPET作为源,取代了RTC中断控制器。我期望QueryPerformanceTimer()和系统时钟是同步的。


1
很遗憾,不是这样的。我进行了一项测试,并绘制了使用GetSystemTime()和QueryPerformanceCounter()获取的值之间的差异,结果如下(显示约9秒钟的数据):http://i56.tinypic.com/k1e6gx.png - fdlm
QueryPerformanceFrequency返回1(TRUE)和频率2727539。这是我用于使用QueryPerformanceTimer进行计时的代码:http://pastebin.com/M9kuit7D - fdlm
这很有趣,也许这会有所帮助:http://tinyurl.com/3k4eywd,特别是关于TSCINVARIANT的部分。很抱歉我帮不了更多了。 - user172783

0

Windows上没有QueryPerformanceTimer()函数。该资源的名称为QueryPerformanceCounter(),它提供了一个在某个更高频率下计数的计数器值。可以通过调用QueryPerformanceFrequency()来获取其递增频率。由于该频率通常在MHz范围内,因此可以观察到微秒级分辨率。

有一些实现可用,例如这个线程或者Windows Timestamp Project


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接