Медленный повтор графика Qwt во встроенном Linux

Я столкнулся с некоторыми проблемами при разработке встроенного решения на основе Qt для Linux. В основном мое приложение строит график QwtPlot с прикрепленными к нему до 8 QwtPlotCurves. QwtPlot::replot() вызывается каждую секунду. Данные поступают из сокета, подключенного к другому приложению .c в той же системе. Оборудование — техасский OMAP.

Проблема в том, что в зависимости от конфигурации повторение становится очень и очень медленным. Чтобы быть более конкретным, если я поставлю 4 кривых для отображения, задержки не ощущается, но если я прикреплю 8 кривых, то начинает появляться лаг/задержка в 400-500 мс.

Я начал отлаживать систему, чтобы найти, где может быть узкое место (есть 3 этапа: первый получает точки и защищает их во временном буфере с небольшой промежуточной обработкой, второй копирует эти точки в векторы точек графика, а третий похож на таймер, который вызывает QwtPlot::replot() для обновления графика), и после отбрасывания двух первых этапов я подумал, что реальная проблема заключалась в методе replot(): я ожидал, что запуск таймера перед вызовом это и вызов QTime::elapsed(), чтобы узнать, сколько времени это заняло, я найду большое число.

Но неправильно! Метод занимает всего 10-15 мс по сравнению с задержкой в ​​400-500 мс, с которой я сталкиваюсь. Имея это в виду, я пришел с вопросом: вызывает ли QwtPlot::replot() что-то, чтобы произошло, а затем переходит после этого, поэтому, пока я вычислил 10 мс, мое приложение фактически выполняет много кода, или я должен сделать вывод, что это огромное время, необходимое для перерисовки, является ошибкой оборудования, которое не может справиться с работой должным образом?

Кстати, использование OpenGL (Qwt предлагает такую ​​возможность) может решить мою проблему? Не будет ли у него какой-то недостаток в том, что он убивает процессор для других задач?

ИЗМЕНИТЬ:

  • Обс. 1: Что касается OpenGL, я уже узнал (в другом вопросе здесь, в SO), что я не смогу использовать его для конкретной встроенной ситуации, которая у меня есть сейчас, поскольку у моего процессора нет графического процессора и любого другого способа использования OpenGL. на самом деле не было бы полезно (подробности см. по этой ссылке).
  • Обс. 2: Обновление повтора выполняется раз в секунду, так что проблема определенно не возникает из-за чрезмерных вызовов повтора, а использование частичного повтора (с помощью QwtPlotDirectPainter или аналогичного) бесполезно.
  • Обс. 3: К настоящему времени я повторно реализовал метод QwtPlot::replot(), так что теперь он вызывает только 3 метода:

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

person Momergil    schedule 27.05.2014    source источник
comment
Какие профилировщики вы пробовали? Вы смотрели, например, результаты из oprofile?   -  person Dark Falcon    schedule 28.05.2014
comment
@DarkFalcon спасибо за комментарий. Я еще не использовал профилировщики, но я попробую oprofile, чтобы посмотреть, что у меня получится.   -  person Momergil    schedule 28.05.2014


Ответы (1)


Я строю графики в реальном времени с более чем 30 данными в одно и то же время, с их операциями fft, на 2 разных графиках, без такой задержки. У меня были свои наблюдения; если вы работаете с данными в реальном времени, вы можете получить некоторые идеи:

Попробуйте удалить устаревшие данные кривой - очистите все, кроме последних 10 секунд, например, - перед повторным построением.

Поскольку вы всегда пишете в future, пытайтесь вызывать replot только тогда, когда график нужно сместить, а не при каждом обновлении.

Попробуйте использовать QwtPlotDirectPainter.

Попробуйте использовать холст и художник.

Попробуйте изменить smt-метод приема, например, используя таймер для проверки сокета, вместо того, чтобы запускать слот для каждого полученного байта.

Всегда старайтесь перемещать таймеры в отдельные потоки.

РЕДАКТИРОВАТЬ: Давайте теперь поговорим о фактических ответах - я слишком быстро прочитал ваш вопрос, извините:

Replot занимает 10 мс, но «поставленные в очередь» повторы кажутся вашей основной проблемой, вы, вероятно, запускаете слишком много повторов (например, каждую миллисекунду), и ваш поток может ставить эти события в очередь.

OpenGL включил QwtPlotGLCanvas, представленный в qwt 6.1, и вы можете протестировать его на примере refreshtest в корневой папке qwt. Из этого вы можете сравнить GPU + CPU только с CPU.

Существует также пример осциллографа, на котором вы можете увидеть, как работает Direct Painter, как использовать его вместо медленного повторного построения, и даже с помощью процессорного рендеринга вы можете получать эффективные обновления для своих графиков.

person baci    schedule 29.05.2014
comment
спасибо за советы. Однако, поскольку он на самом деле не отвечает на вопрос, я не буду отмечать его как правильный ответ, хорошо? Только один вопрос: что вы имели в виду под попыткой удалить устаревшие данные кривой - очистить все, кроме, например, последних 10 секунд - перед повторным построением? Я не понял этой фразы :С - person Momergil; 30.05.2014
comment
если ваши данные представляют собой огромные векторы, вы постоянно добавляете входящие байты; тогда повтор не эффективен. вы также можете получить исключения памяти. просто попробуйте стереть старые (устаревшие) значения из этих векторов. отредактировал мой ответ - person baci; 30.05.2014
comment
Ох, хорошо. Ну, это не мой случай: вектор имеет фиксированный размер. Но спасибо за разъяснение! - person Momergil; 30.05.2014