У меня есть приложение для визуализации данных (параллельные координаты). Это включает в себя рисование множества линий на экране. Приложение для огромных наборов данных. Тестовый набор данных включает в себя ~ 2,5 млн строк (2527700 точных). Экран будет загроможден, но на нем будет какая-то картина. Приложение имеет возможность масштабирования по X и Y. При типичных уровнях масштабирования оно рисует около 300K линий. Приложение написано на Qt, и время, необходимое для рендеринга, является респектабельным. Типичные числа (время в мс)
Время: 496
Нарисовал 1003226 линий
Время: 603
Нарисовал 1210032 линии
Время: 112
Нарисовал 344582 строки
Время: 182
Нарисовал 387960 линий
Время: 178
Нарисовал 361424 строки
Время: 222
Нарисовал 676470 линий
Время: 171
Нарисовал 475652 линии
Время: 251
Нарисовал 318709 линий
Время заняло: 5
Нарисовал 14160 строк
Время: 16
Нарисовал 27233 линии
Следующий сегмент кода используется для определения времени и количества нарисованных отрезков. Рендеринг происходит за пределами экрана (QImage с форматом Format_ARGB32_Premultiplied). Размер QImage составляет максимум 1366 x 768. Тип сегментов — QVector.
QTime m_timer;
m_timer.start();
painter.drawLines(segments);
qDebug() << "Time taken: " << m_timer.elapsed();
painter.end();
qDebug() << "Drew " << segments.size();
Этот QImage кэшируется для сохранения будущих розыгрышей. Я никогда не использовал DirectX. Будет ли прямой 2D-рендеринг давать больше преимуществ в производительности, чем у меня уже есть. Есть ли способ улучшить эти цифры?
Если прямой 2D рендеринг может улучшить эти цифры, какой технологический стек использовать? Будет ли лучше использовать C # / SharpDX? Я спрашиваю об этом, потому что Qt может выполнять DirectX только через перевод (не знаю, сколько это будет стоить), и так как приложение преимущественно для Windows, C # может облегчить разработку. процесс.
Возможно, было бы оптимальным создать собственную функцию рисования линий, работающую непосредственно с буфером памяти QImage. Там вы можете сделать некоторые предположения, которые художник Qt, вероятно, не может сделать, и добиться лучшей производительности. Затем перетащите изображение на экран сглаженным (и, возможно, увеличенным?) С помощью QGLWidget.
Хороший код рисования линий: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#Simplification .
Хотя для C ++ и реализации буфера памяти, он может быть дополнительно оптимизирован путем замены x0
а также y0
координаты с одним указателем.
Что наиболее важно, вы можете затем сделать рисование линий встроенным в ваш цикл линий и иметь нулевые вызовы функций при повторении более миллиона линий.
Если вы разрешите блеющей части выполнять сглаживание, вы можете просто установить слово памяти на пиксель, не проверяя, какое это перо и т. Д.
Кроме того, выполняя увеличение HW до любого желаемого целевого разрешения, вы можете свободно оптимизировать размер QImage для получения нужного шаблона, отдельно от его отображения на экране.
Если вы можете иметь строки, в основном отсортированные по координате Y, это поможет с кэшированием, так как установка пикселей последовательных линий будет ближе в памяти в буфере QImage.
Как бы вы это ни делали, включите оптимизацию (флаг -O3 для gcc, не уверен в компиляторе MS), по умолчанию это не максимум, по крайней мере, для gcc.
Еще одна вещь, которую вы можете сделать, это распараллелить рисование на уровне изображения, которое будет работать даже с QPainter. Разрешается рисовать на QImage не в главном потоке, а Qt позволяет просто отправлять QImages в качестве параметра сигнала из потоков рисования в поток GUI. То, что вы делаете, сильно привязано к процессору и памяти, так что лучше иметь количество потоков рисования, равное реальному числу ядер, не считая гиперпоточность.
Не знаю Qt, но для Direct2D у вас не будет хорошей производительности при рисовании миллионов сглаженных линий в Windows 7 (без последнего обновления IE10 / SP). В Windows 8 Direct2D был немного улучшен, но я не уверен, что он справится с такой скоростью. Если вы хотите добиться более высокой производительности, вам придется напрямую использовать Direct3D с поверхностью MSAA или, возможно, с каким-либо последующим эффектом пространства пространства, например FXAA, или использовать методы сглаживания с поддержкой геометрии, такие как GPAA / GBAA. Проверьте «Подходы фильтрации для сглаживания в реальном времени«Полный список современных методов сглаживания в реальном времени.
Может быть, я не буду отвечать на ваш вопрос напрямую, но:
Я предполагаю, что Qt использует стандартные системные подпрограммы для выполнения графических операций, поэтому здесь подразумеваются GDI и / или GDI +. Ни один из них, если быстро, оба делают все вычисления на процессоре. С другой стороны, Direct2D из DirectX11 + пытается по возможности ускорять рисование с использованием мощности графического процессора, поэтому может работать быстрее
Я не очень хорошо знаю Qt, но я думаю, что вы должны быть в состоянии получить дескриптор окна (= control), на котором хотите каким-либо образом рисовать (даже если это означает использование WinAPI — всегда есть способ). Если это так, вы можете обойти все механизмы Qt и рисовать непосредственно в этом окне, используя DirectX без дополнительных затрат.
Что касается SharpDX — я не знал, что такая библиотека существует, спасибо за информацию. Они опубликовали статью, информирующую о выполнении операции, вы можете проверить это: http://code4k.blogspot.com/2011/03/benchmarking-cnet-direct3d-11-apis-vs.html . В любом случае, кажется, что это более или менее простая оболочка вокруг заголовков DirectX, так что это не должно увеличить нагрузку на ваше приложение (если производительность не снижается). действительно критический).