Qt高分辨率计时器

时间:2013-03-31 15:01:29

标签: qt timer

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

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

我没有使用系统时钟,而是考虑与音频时钟同步,因为我已经有了音频输出流,但我不认为Qt为此提供了功能。

从C ++ / Qt开始,在正常情况下,以特定时间间隔调用函数的某个精确时钟同步的最简单(和/或最好)方法是什么?

2 个答案:

答案 0 :(得分:5)

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

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

您需要做的事情如下:

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

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

  3. 当然你需要处理花费时间太长的帧,错过的计时器等等。但这是唯一能让它工作的理智方式。

    或者,您可以在音频缓冲区已耗尽到某个级别时使用通知。 Qt 5可能会为此提供API。

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

    如果您希望进一步权衡功耗以获得时序精度,you can dedicate a hyper thread to busy waiting while polling a high resolution time source。这不是一件轻松的事情,但对于某些应用,比如测试线束,它可能没问题。笔记本电脑/笔记本电脑/平板电脑用户会讨厌你。

    请注意那里提出的fantastic article提出了一个无法工作的解决方案,在没有真正(相对于想象的)网卡“定时器”的情况下会以某种方式影响套接字轮询等待。

答案 1 :(得分:0)

QTimer是一个事件循环计时器。这意味着它只在偶数循环可以自由处理事件时才提供。如果条件是“正确”,它也可以跳过。

据我所知,Qt中没有确定的点火计时器。您必须使用特定于平台的呼叫。

一个可能的Qt解决方案可能是与使用msleepusleep进行计数的主GUI线程分开的线程。你可以让一个计时器线程休眠一段时间并唤醒,唤醒另一个用信号量执行实际工作的线程然后再回到睡眠状态。工作线程完成一部分工作,然后再次等待信号量。

QThread::sleep不依赖于事件循环,可能具有更高的准确性。