用于定期调用的现代高分辨率计时器

Posted

技术标签:

【中文标题】用于定期调用的现代高分辨率计时器【英文标题】:Modern high res timer for periodic calls 【发布时间】:2015-03-21 11:39:34 【问题描述】:

关于 *** 上的高分辨率计时器已经有很多说法。但很明显,该解决方案是一个移动的目标,最佳实践正在发生变化。

我需要创建一个高分辨率计时器,它每 10 毫秒回调一次,以实现一致的 100Hz。目标平台是 Windows 7 及更高版本。

这个exact question was asked in 2009,但我相信事情可能已经发生了变化。

多媒体定时器看起来是一个很好的解决方案,但 MSDN 说它们是 depreciated,被 CreateTimerQueueTimer 取代。但是关于 *** 的其他答案表明 CreateTimerQueue 计时器不如 timeSetEvent 准确。

所有答案都一致地指出了使用 timeBeginPeriod 将 Windows 计时器分辨率设置为低值的要求。

综上所述,今天在 C 中实现上述预期目标的最佳方法是什么。

【问题讨论】:

您需要每 10 毫秒回调一次,但您要寻找的准确度是多少? 0.1?, 1%? 10%? 您可以使用 MinGW 和 timeb.h,这将为您提供 struct timeb,包括毫秒。 我真的不认为 win7 在这方面做得很好,因为它不是作为实时操作系统设计的。如果您有非常严格的实时限制,请尝试其他一些实时操作系统,它可能提供了一大堆用于调度和计时的 API。 如果您说您使用的是 C,为什么还要有 c++ 标签? C 和 C++ 是不同的语言,我在您的问题中没有看到 C++ 特定的内容。 @mins 大约 0.1 毫秒是关于我正在寻找的准确性。或者换一种说法 +/-1%。 【参考方案1】:

但 MSDN 说它们已折旧

当您看到这样的弃用警告时,能够在各行之间进行阅读非常重要。是的,微软肯定希望每个人都停止使用多媒体计时器。它们被严重滥用,对业务非常不利。实际上让程序员停止使用它们是白日梦,但 CreateTimerQueueTimer() 不是替代方案。

对业务不利,因为 Microsoft 喜欢在移动计算领域保持竞争力。和多媒体计时器是一个非常糟糕的匹配,它们是电池寿命的谋杀。大多数使用它们的程序将时钟中断率提高到允许的最大值,每秒 1000 次。有一个后门可以达到 2000 年。而且很难阻止他们这样做,尤其是当他们的竞争对手提供他们的软件 away for free 时。他们没有任何动力去解决这个问题,因为这让他们的移动操作系统看起来不错。而且微软不能杀死这样非常流行的应用程序。

微软有一个移动操作系统,通过 WinRT api 公开。如果弃用非常困难,那么当您使用这些计时器时,您的应用程序无法获得商店验证程序的批准。但它并没有多大用处,他们的客户喜欢继续使用他们的桌面应用程序。

如果您想要 100 Hz 的更新率,那么您使用 timeBeginPeriod() 和 timeSetEvent(),没有其他方法。并避免 WinRT。由于它实际上只比默认值差 1.5 倍,因此没有明显的理由担心功耗。将激光设置为眩晕并使用有效的方法。

【讨论】:

感谢“Microsoft 方式”的清晰说明。我很幸运,这是一个控制系统,本质上必须插入电源。因此,我很高兴通过消耗功率来达到效果。【参考方案2】:

你愿意边走边烧CPU吗?在繁忙的循环中调用 QueryPerformanceCounter()。您将获得微秒精度,并对电池寿命产生适当的不利影响。您还可以将进程优先级提升到 REALTIME_PRIORITY_CLASS 并将工作线程的优先级提升到 THREAD_PRIORITY_TIME_CRITICAL(或降低一两个等级),从而将其提高到 11 个。这样做当然会产生负面影响。

【讨论】:

以上是关于用于定期调用的现代高分辨率计时器的主要内容,如果未能解决你的问题,请参考以下文章

C ++ Windows中的高分辨率计时器库? [复制]

C中的跨平台高分辨率计时器?

实现高分辨率计时器的最佳方法

JavaScript 跨浏览器,高分辨率计时器功能(替换Date()。getTime())。

Linux高精度定时器hrtimer使用实例

reedlau高精度 高分辨率 计时函数 Linux