用于定期调用的现代高分辨率计时器
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 个。这样做当然会产生负面影响。
【讨论】:
以上是关于用于定期调用的现代高分辨率计时器的主要内容,如果未能解决你的问题,请参考以下文章