Qt高分辨率定时器

标签 qt timer

我正在为使用 C++ 的系统编写模拟器,使用 Qt 进行 UI、事件处理等。显然,我需要有一个准确的时序引用。现在,我使用具有适当间隔的 QTimer(NTSC 为 16.66667 毫秒,PAL 为 20 毫秒)但正如预期的那样,它的准确性非常糟糕。有时计时器以 50 FPS 的速度触发,有时以 120 FPS 的速度触发。

我意识到大多数操作系统都有一些功能可以提供精确到微(或纳)秒级的时间戳。 (即 Windows 上的 QueryPerformanceCounter。)

除了使用系统时钟,我还考虑同步到音频时钟,因为我已经有了一个音频输出流,但我认为 Qt 没有为此提供功能。

从 C++/Qt 同步到某个精确时钟以在特定时间间隔调用函数且在正常情况下几乎没有抖动的最简单(和/或最佳)方法是什么?

最佳答案

高分辨率时间戳并不意味着内核中有一种机制可以在达到高分辨率时间戳的给定值时唤醒休眠线程。

在 Qt 和 Windows 上,当您的计时器超时“足够短”(<= 10ms IIRC)时,Qt 将强制系统的滴答间隔为 ~1ms(1000Hz 或 1024Hz)。

你需要做的事情如下:

  1. 使用 QElapsedTimer 跟踪高分辨率时间(在内部它使用 Windows 上的性能计数器或提供最高分辨率时间的任何东西)。

  2. 根据#1 的高分辨率时间值设置定时器到期时间。

当然,您需要处理耗时过长的帧、错过的计时器等。但这是让它正常工作的唯一合理方法。

或者,您可以在音频缓冲区耗尽到一定水平时使用通知。 Qt 5 可能为此提供 API。

可以在任何操作系统上生成更好计时的唯一方法是使用专用硬件而不是通用计时器滴答。这样的硬件可能像在环回模式下运行的串行端口一样简单。作为一个额外的、独立的可等待事件源,它可能非常有用。音频缓冲区交换也可以是一个很好的计时来源。

如果您想进一步权衡功耗与计时精度,you can dedicate a hyper thread to busy waiting while polling a high resolution time source .这不是一件轻而易举的事情,但对于某些应用程序,比如测试工具,它可能没问题。笔记本电脑/笔记本电脑/平板电脑用户会因此讨厌你。

当心 fantastic article在那里提出了一个没有机会工作的解决方案,在没有真正的(而不是想象的)网卡“计时器”的情况下,它会以某种方式影响套接字轮询等待。

关于Qt高分辨率定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15730765/

相关文章:

javascript - 如何根据时间降低 qml 中的旋转速度?

c++ - 在 Qt 的子线程中调用函数?

c++ - 如何在 Qt 小部件应用程序中翻译来自外部文件的字符串?

java - 每次从 Swing 类中的 main 调用方法时的 sleep 或等待时间

wxwidgets - 基本的 wxWidgets 计时器

ios - 在函数调用中发送到实例的无法识别的选择器

c++ - Qt Creator 中依赖文件的自动复制

qt - 在 QML Webview 中使用相对 url

C# - 你如何停止计时器?

javascript - 倒计时不起作用