PDA

View Full Version : Parallel compute-and-display solutions?



nsvinc
15th August 2013, 19:17
I am developing an app, which displays many graphs on a QGLWidget in real time, similarly to roll view in a digital oscilloscope.

For a single graph, the drawing sequence is:
- get samples from a data source
- process these samples with respect to X/Y scaling and window width/height, and store the result in a buffer
- render - draw a grid, informational text and the contents of the buffer

The processing step is really time consuming, for many reasons - one of them is the scaling part, other are interpolation routines.

All the graphs are drawn on a common QGLWidget using QPainter. (lines are drawn using QPolygon, not separate pixels or lines)

For now, I followed the standard approach, that is, do all the work in the paint event handler - compute the buffer contents for all visible graphs, and paint them. The refresh rate is 25ms. Refreshing 20 graphs at this rate yields a >100% load ;) on one 2.6GHz AMD Athlon64 core, which causes stuttering and makes the UI quite unusable.

The solution is quite obvious - move the processing to another thread (and allow it to execute on another core). Or better, write a QRunnable wrapper class for a graph and use a thread farm (QThreadPool) to exploit all available processor cores.

But how to paint these graphs?
I figured out something like that:
- enable painting outside the paint event in the QGLWidget
- in the paint event handler, do nothing more than enqueue graphs, marked as visible, for processing (in the thread farm)
- create a signal in the wrapper class which will be thrown when processing is done
- create a drawer object which receives the 'processing done' signals (by async queued connection) and does the real painting on the QGLWidget
- push this drawer object to another thread

What I expect, is asynchronous (and parallel) graph processing and sequential (but still asychronous) graph painting. All this is triggered by a single event (push to the thread farm for processing).

Is this solution acceptable?