Windows 上的微秒分辨率时间戳

新手上路,请多包涵

如何在 Windows 上获取微秒分辨率时间戳?

我正在寻找比 QueryPerformanceCounterQueryPerformanceFrequency 更好的东西(这些只能为您提供自启动以来经过的时间,如果它们在不同的线程上被调用,则不一定准确 - 也就是说, QueryPerformanceCounter 可能在不同的 CPU 上返回不同的结果。还有一些处理器会调整其频率以节省电量,这显然并不总是反映在它们的 QueryPerformanceFrequency 结果中。)

_有为 Windows 实现持续更新的高分辨率时间提供程序_,但它似乎并不可靠。 当微秒 很重要时,它看起来很棒,但它不再可供下载。

另一个资源是 _在 Windows XP 下获取准确的时间戳_,但它需要一些步骤,运行一个帮助程序加上一些初始化的东西,我不确定它是否适用于多个 CPU。

我还查看了 Wikipedia 文章 _Time Stamp Counter_ ,这很有趣,但没那么有用。

如果答案只是用 BSD 或 Linux 来做这件事,那会容易得多,这很好,但我想确认这一点,并解释一下为什么这在 Windows 中如此困难,而在 Linux 和 BSD 中如此容易。都是一样的好硬件…

原文由 Nikhil 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 657
2 个回答

我相信这仍然有用: 系统内部:提供多媒体计时器支持的指南

它很好地解释了各种可用的计时器及其限制。您的大敌可能不是分辨率,而是延迟。

QueryPerformanceCounter 并不总是以 CPU 速度运行。事实上,它可能会尝试避免 RDTSC ,尤其是在多处理器(/多核)系统上:它将在 Windows Vista 和更高版本上使用 HPET (如果可用)或 ACPI/PM 计时器。在我的系统(Windows 7 x64,双核 AMD)上,计时器以 14.31818 MHz 运行。

对于早期的系统也是如此:

默认情况下,Windows Server 2003 Service Pack 2 (SP2) 对所有多处理器 APIC 或 ACPI HAL 使用 PM 计时器,除非确定 BIOS 是否支持 APIC 或 ACPI HAL 的检查过程失败。”

问题是,当检查失败时。这仅仅意味着您的计算机/BIOS 在某种程度上被破坏了。然后您可以修复您的 BIOS(推荐),或者至少暂时切换到使用 ACPI 计时器(/usepmtimer)

从 C# 很容易 - 没有 P/Invoke - 使用 Stopwatch.IsHighResolution 检查高分辨率计时器支持,然后查看 Stopwatch.Frequency 。它将在内部进行必要的 QueryPerformanceCounter 调用。

还要考虑,如果计时器坏了,整个系统将受到严重破坏,并且通常表现得很奇怪,报告负的经过时间,减慢等等 - 不仅仅是你的应用程序。

这意味着您实际上可以依赖 QueryPerformanceCounter。

…与流行的看法相反, QueryPerformanceFrequency() “系统运行时无法更改”

编辑:正如 QueryPerformanceCounter() 上的文档所述,“调用哪个处理器无关紧要” - 事实上,只有当 APIC/ACPI 检测失败并且系统求助时,才需要使用线程关联进行整个黑客攻击使用 TSC 。这是一个不应该发生的度假胜地。如果它发生在较旧的系统上,则可能有制造商提供的 BIOS 更新/驱动程序修复。如果没有,则 /usepmtimer 引导开关仍然存在。如果这也失败了,因为系统除了 Pentium TSC 之外没有适当的计时器,您实际上可能会考虑弄乱线程关联 - 即使这样,其他人在页面的“社区内容”区域提供的示例是具有误导性,因为由于在每次启动/停止调用上设置线程亲和性,它具有不可忽略的开销——这会引入相当大的延迟,并可能首先降低使用高分辨率计时器的好处。

Game Timing and Multicore Processors 是关于如何正确使用它们的建议。请考虑它现在已经 5 年了,当时完全符合/支持 ACPI 的系统较少 - 这就是为什么在抨击它时,这篇文章详细介绍了 TSC 以及如何通过保持仿射来解决其局限性线。

我相信现在要找到一台支持零 ACPI 且没有可用 PM 计时器的普通 PC 是一项相当艰巨的任务。最常见的情况可能是 BIOS 设置,当 ACPI 支持设置不正确时(有时可悲的是出厂默认设置)。

轶事告诉 八年前,在极少数情况下情况有所不同。 (读起来很有趣,开发人员围绕设计“缺点”工作并抨击芯片设计师。公平地说,反之亦然。:-)

原文由 Andras Vass 发布,翻译遵循 CC BY-SA 3.0 许可协议

QueryPerformanceCounter / QueryPerformanceFrequency,处理器速度分辨率

请注意多线程。处理器上的每个核心都可以有自己的计数器。

在 Windows XP 下获取准确的时间戳 中提供了更多信息。

如果您最终不得不求助于这种方法:

当我试图手动将数据写入串行端口(用于红外发射器)时,我发现将进程和线程优先级设置为最大值(实时)大大提高了它的可靠性(因为没有错误),这是必须的如果我也记得的话,它的分辨率大约是 40 kHz,所以它应该保持足够精确到毫秒分辨率。

原文由 matt 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题