Настройка производительности OpenGL для пропускной способности геометрии
Это, вероятно, было задано снова и снова, но я не мог найти ничего полезного, так что он снова возвращается...
В моем приложении мне нужно отобразить довольно большую сетку (пару миллионов треугольников или больше), и у меня возникли проблемы с получением приличных скоростей кадров из нее. Процессор практически не работает, поэтому я определенно привязан к GPU. Изменение разрешения не влияет на производительность, поэтому оно не является фрагментарным или растровым.
Сетка динамическая (но локально статическая), поэтому я не могу сохранить все это на видеокарте и сделать ее одним вызовом. По причинам, связанным с конкретными приложениями, данные хранятся в виде октодекса с вокселями в листьях, с помощью которых я получаю усечение в основном бесплатно. Данные вершин состоят из координат, нормалей и цветов - не используются текстуры или шейдеры.
Мой первый подход состоял в том, чтобы просто извлечь все из памяти, используя один большой STREAM_DRAW
VBO, который оказался слишком медленным. Моя первоначальная мысль заключалась в том, что я, возможно, перегружал автобус (толкал ~ 150 MiB за кадр), поэтому я реализовал схему кэширования, в которой хранится геометрия, недавно используемая для рендеринга объекта в статических VBOs на графической карте, причем каждый VBO хранит пару 100 KiB на пару данных о ценности MiB (хранение большего количества на VBO дает больше рутинного кэша, поэтому здесь есть компромисс). Ниже приведен пример того, как выглядят данные, где все окрашенные в красный цвет выводятся из кэшированных VBOs.
Пример отображаемых данных http://gimaker.users.sourceforge.net/0010.png
Как видно из приведенных ниже цифр, я не вижу впечатляющего увеличения производительности при использовании кеша. Для полностью статической сетки около 1 миллиона треугольников я получаю следующие частоты кадров:
- Без кеширования: 1,95 Гц
- Кэширование с использованием вершинных массивов: 2.0 Гц ( > 75% сетки кэшируется)
- Кэширование с использованием
STATIC_DRAW
VBOs: 2,4 Гц
Итак, мои вопросы: как мне ускорить это? То есть:.
- Какой рекомендуемый формат вершин для получения достойной производительности? Я использую перемеженное хранилище с позициями и нормалями как
GL_FLOAT
и GL_UNSIGNED_BYTE
для цветов, с одним байтом заполнения, чтобы получить 4-байтовое выравнивание (28 байт/общее количество вершин).
- Может ли помочь использование одного и того же буфера для нормалей для всех моих ящиков (все поля выравниваются по оси, поэтому я могу выделить обычный буфер размером с самой большой кэш-записью и использовать его для всех).
- Как узнать, какая часть трубопровода является узким местом? У меня нет впечатляющей видеокарты (Intel GM965 с драйверами для Linux с открытым исходным кодом), поэтому я могу достичь своего предела. Сколько можно ожидать от типичного оборудования (интегрированная графика на 2-3 года, современная интегрированная графика, современная дискретная графика)?
- Любые другие советы о том, как вы справитесь с этим, ловушки и т.д.
Мне не интересны ответы, предлагающие LOD (я уже тестировал это), советы для конкретных поставщиков или использование функций OpenGL от чего-либо позже 1.5.
Ответы
Ответ 1
Вам, вероятно, не понравится этот ответ....
Я нашел вашу проблему: Intel GM965 с драйверами с открытым исходным кодом Linux
Пока моя текущая работа не затрагивает ваш объем данных, мы отобрали несколько миллионов вершин в VBO, а графические аппаратные средства/драйверы Intel оказались бесполезными. Получите себе карту NVidia (и переходите к использованию двоичного драйвера, она просто работает), и все будет готово. Даже не должно быть текущим поколением, хотя верхний конец Quadro (если работа оплачивается) или топ-серии GTX 400 (если вы платите или просто пытаетесь сэкономить несколько долларов на работе) должны делать только штрафы с последними водители. Вы также можете попытаться найти машину с этим оборудованием для проверки, если обновление вашей машины не является вариантом.
Ответ 2
Я бы сначала использовал профилировщик производительности (например, gDEBugger), поэтому вы можете выяснить, ограничены ли вы вершины, фрагменты или шины, и т.д. Невозможно угадать, какие оптимизации выполнять в таком конкретном случае (драйверы с открытым исходным кодом Intel +).
Вы также попробовали режим VA? Используете ли вы glDrawElements
? glDrawArrays
? Является ли вершинный кеш данных дружественным (pre и post transform)?
Ответ 3
Я не знаю о вашей "сетке", но кажется, что все они кубики. Если это возможно, сделайте единый куб объединения в список отображения и выполните масштабированную версию этого списка отображения. Это часто дает 10-кратное ускорение, поскольку шина не накачивается данными вершин или из-за потери видеопамяти.
Конечно, это зависит от вашей способности изменять данные. Это может быть не так, если на самом деле это не так.