0

在为 Linux 开发基于 Qt 的嵌入式解决方案时,我遇到了一些问题。基本上,我的应用程序绘制了一个 QwtPlot 图,其中最多附有 8 个 QwtPlotCurve。每 1 秒调用一次 QwtPlot::replot()。数据来自连接到同一系统中另一个 .c 应用程序的套接字连接。硬件是德州的 OMAP。

问题是根据配置,重新绘制变得非常非常慢。更具体地说,如果我显示 4 条曲线,则不会感觉到延迟,但如果我附加 8 条曲线,则开始出现 400-500 毫秒的延迟/延迟。

我开始调试系统以找出瓶颈可能在哪里(有 3 个阶段:第一个阶段接收点并将它们保护在一个临时缓冲区中,中间几乎没有处理,第二个阶段将这些点复制到绘图点向量中,第三个阶段就像一个调用 QwtPlot::replot() 来更新图形的计时器)并且在丢弃了两个第一阶段之后,我认为真正的问题在于 replot() 方法:我希望在调用之前启动一个计时器它并调用 QTime::elapsed() 来查看花费了多少时间,我会找到一个很大的数字。

但是错了!与我面临的 400-500 毫秒延迟相比,该方法只需要 10-15 毫秒。考虑到这一点,我提出了一个问题: QwtPlot::replot() 是否调用了某些事情发生然后继续执行,所以当我计算 10 毫秒时,我的应用程序实际上正在运行大量代码,或者我应该得出结论重新绘制所需的大量时间是硬件的故障,谁不能适当地处理这项工作?

顺便说一句,使用 OpenGL(Qwt 提供这种可能性)可以解决我的问题吗?它不会有一些为其他任务杀死处理器的缺点吗?

编辑:

  • 观察。1:关于 OpenGL,我已经了解到(在 SO 中的另一个问题中),由于我的处理器没有 GPU 和任何其他使用 OpenGL 的方式,我将无法将它用于我现在所拥有的特定嵌入式情况实际上不会有帮助(有关详细信息,请参阅此链接)。
  • 观察。2:重新绘制刷新每秒完成一次,所以问题肯定不是来自过多的重新绘制调用,并且使用部分重新绘制(通过 QwtPlotDirectPainter 或类似的方式)是徒劳的。
  • 观察。3:现在我重新实现了 QwtPlot::replot() 方法,所以它现在只调用 3 个方法:

    updateAxes();
    
    poCanvas->invalidateBackingStore();
    poCanvas->update();
    
4

1 回答 1

1

我用他们的 fft 操作同时用 30 多个数据实时绘制到 2 个不同的图上,没有这样的延迟。我有我的观察;如果您正在处理实时数据,您可以获得一些想法:

尝试删除陈旧的曲线数据 - 清除所有内容,例如最后 10 秒 - 在重新绘制之前。

由于您总是写信到future,因此仅在需要移动情节时才尝试调用 replot ,而不是在每次更新时调用。

尝试利用QwtPlotDirectPainter.

尝试利用画布画家属性。

尝试更改您的接收方法 smt ,例如使用计时器检查套接字,而不是为每个接收到的字节触发一个插槽。

始终尝试将计时器移动到单独的线程。

编辑: 现在让我们谈谈实际答案 - 我读得太快了你的问题,对不起:

重新绘制需要 10 毫秒,但“排队”重新绘制似乎是您的主要问题,您可能触发了太多重新绘制(如每毫秒),并且您的线程可能正在排队这些事件。

qwt 6.1 中引入了OpenGL QwtPlotGLCanvas,您可以从qwt 根文件夹下的refreshtest示例对其进行测试。从中您可以将 GPU+CPU 与仅 CPU 进行比较。

还有一个示波器示例,您可以看到直接画家的工作原理,如何利用它而不是缓慢地重新绘制,即使使用 CPU 渲染,您也可以获得对绘图的有效更新。

于 2014-05-29T22:54:09.063 回答