Стоимость OpenGL команд (комментарии)
Это сообщение сгенерировано автоматически.
Обновление:
Сделал бенчмарк. В самом конце статьи можно скачать: "Исходный код всех примеров"
Запускаем BENCHMARK_OpenGL_API_overhead.exe (результаты пишет в benchmark_results.txt), публикуйте свои результаты
Спасибо за статью. Но не были проведены замеры таких полезных вещей как GL_ARB_multibind/GL_ARB_sampler_objects
Andrey
> Но не были проведены замеры таких полезных вещей как
> GL_ARB_multibind/GL_ARB_sampler_objects
О да, это очень полезная вещь. fps просто в разы увеличивается ?
_Wizard_
Я правильно понял, что UBO инстансинг немного быстрее VBO (divisor) ? А можно повторить тесты для Nvidia ?
А в чем разница между ARRAY_OF_TEXTURES_TEST и ARRAY_OF_TEXTURES_TEST?
_Wizard_
>Стоит конечно весьма осторожно относиться к данным измерениям, т.к. они будут меняться в зависимости от версии драйвера и железа.
С этим нельзя не согласиться, но непонятно что это за проценты такие "3550%". И самое главное по сути glBindTexture и подобные команды нулевые и выполняются исключительно на CPU, виртуальные, все конечно зависит от драйвера. Или это прибавка к нагрузки самой отрисовки при использовании данной команды? (то есть прирост отрисовки если произошла смена состояния)
Поскольку реальная инициализация происходит во время выполнения glDraw... или чтения записи в соответствующий буфер, все остальные данные хранятся локально на CPU, по этому выгодней использовать массивы/буферы индексов-текстур юниформов и тд. то есть хранить практически все данные на стороне GPU (то есть не только вершины и саму текстуру но и идентификаторы их буферов), что позволяет сократить обмен данных между CPU и GPU практически до нельзя.
_Wizard_
>Соответственно, нужно как то передать шейдеру эти параметры. Делается это специальными командами: glUniform*
Но ведь можно же массивом передавать ?
innuendo
> Но ведь можно же массивом передавать ?
Память юниформов не резиновая. Засунул сотню костей одновременно - и все, приехали.
А, кстати, насчет оптимизации передачи юниформов (скажем, вместо матрицы-кости передавать кватернион и смещение) хотелось бы прояснить вопрос. В спеке написано, что значения, зависящие только от констант и юниформов, тоже являются юниформами, то есть вычисляются единожды, а не в каждом выполнении шейдера (что вполне логично). Но если мне правильно подсказывает моя логика, из-за того, что память юниформов - особенная (параллельное чтение всеми ядрами), то и вычисленные в шейдерах юниформы тоже должны отжирать и без того драгоценную юниформ-память.
Dmitry_Milk
> Память юниформов не резиновая. Засунул сотню костей одновременно - и все,
> приехали.
Причём тут память ? Вопрос про скорость засылки же
_Wizard_
очень инетерсная инфа. по твоим данным, скорость DIP'а относительно всяких стейтов вовсе не так уж велика. может, выложить тестбед, чтобы быстро собрать данные с разных железок у пользователей?
Andrey
>Спасибо за статью. Но не были проведены замеры таких полезных вещей как GL_ARB_multibind/GL_ARB_sampler_objects
очень много всего, конечно хотелось бы все замерить - времени мало, много планов на другие вещи
innuendo
>Я правильно понял, что UBO инстансинг немного быстрее VBO (divisor) ?
да, он самый быстрый.
в целом UBO, VBO(divisor), SSBO, TEXTURE instancing +- равны по скорости.
Удивил немного TBO - он 3.3 раза дороже чем через UBO. Поэтому выгодней делать через текстуру.
Ну и определенно на каждый дип передавать параметры через юниформы - это зло. Это кажется очевидно. Смешно то, что у нас на проекте именно так) И все хаят gl за его тормознутость, хотя на самом деле нужно спроектировать рендер правильно, ну и очень много кода переписать.
>А можно повторить тесты для Nvidia ?
на следующей неделе только получится
foxes
>А в чем разница между ARRAY_OF_TEXTURES_TEST и ARRAY_OF_TEXTURES_TEST?
упс - поправил, второе имелось ввиду TEXTURES_ARRAY_TEST, специальное расширение позволяющее хранить кучу текстур в массиве на гпу и обращаться к ним по индексу
тестом хотелось показать стоимость установки текстур
>непонятно что это за проценты такие "3550%". И самое главное по сути glBindTexture и подобные команды нулевые и выполняются исключительно на CPU...
>Поскольку реальная инициализация происходит во время выполнения glDraw
поэтому
1. сначала я замерил стоимость glDrawRangeElements и отталкиваясь от этого
2. делал другие тесты, с таким же количеством glDraw* + дополнительные АПИ вызовы
я не ставил таймер на конкретный АПИ вызов - я ставил таймер на весь тест, 1к-2к дипов, вместе с glDraw*. Только так можно 'посчитать' стоимость вызова.
%показывают во сколько раз стоимость соответствующего АПИ вызова дороже glDrawRangeElements.
Нам нужно было что-то взять за единицу измерения, чтобы показать относительную стоимость.
Это очень полезная информация, поскольку стоимость дипов разная в зависимости от количества смен различных стейтов.
Сам glDraw* не слишком дорогой. Смена текстур например почти в 3 раза дороже! Смена шейдера в 10 раз дороже!
Поэтому потенциально хорошей оптимизациями будут:
- запаковка текстур в атлас или текстурный массив. На старте уровня скажем
- объединить шейдеры в 1, добавив немного ветвлений/бранчинга
- собрать данные всех инстансов, всех дипов в 1 массив и 1 командой передать на гпу. Для каждого дипа просто указывать по какому смещению находятся данные. В Battlefield 3+ так например (и у всех нормальных людей так)
Смысл всех измерений в том, что можно просто посчитать количество различных АПИ вызовов в игре и прикинуть потенциальную выгоду от различных оптимизаций.
innuendo
>Но ведь можно же массивом передавать ?
можно да, у меня 4к юниформов помоему за раз можно передать.
просто смысл теста был в замере стоимости АПИ вызова.
поэтому надо собирать данные в большой массив и засылать одной командой.
Dmitry_Milk
>А, кстати, насчет оптимизации передачи юниформов (скажем, вместо матрицы-кости передавать кватернион и смещение) хотелось бы прояснить вопрос
статья про замер стоимости АПИ вызовов.
и нет - кватернионы в вершинном шейдере дороже будут:
- Трансформация матрицей: 3 раза dot-product
- Повернуть вектор кватернионом: 2 cross-products, 2 dot-products, 3 vector-scaler multiplies, 3 vector additions + смещение
_Wizard_
> я ставил таймер на весь тест, 1к-2к дипов, вместе с glDraw*.
Если не иметь представления о том что реально под капотом то без этого уточнения может показаться что отдельный glBindTexture много жрет. Надо повышать доступность текста для большего круга читателей. Было бы замечательно если бы имелись ссылки на пару основных терминов иначе выглядит как сленг.
В принципе у тебя это указанно:
> В стоимость dip'а обычно включают все сопутствующие смены стейтов, а не саму конмаду.
Можно просто дополнить эту фразу еще одним предложением о конкретно проведенных тестах.
_Wizard_
> да, он самый быстрый
> > можно повторить тесты для Nvidia ?
> на следующей неделе только получится
Жду с нетерпением :)
Suslik
>очень инетерсная инфа.
спасибо
>по твоим данным, скорость DIP'а относительно всяких стейтов вовсе не так уж велика.
да, именно так. Если всяких других АПИ вызовов не делать, то можно нащелкать 1к дипов за 0.2 мс.
что то типа MultiDrawIndirect 'для бедных'. Стоимость MultiDrawIndirect - 0.13 ms на 1к дипов. Им конечно можно гораздо больше дипов делать за 1 раз, 'формировать' на гпу... но тем не менее, glDraw* относительно дешевый.
Ну и опять же повторюсь - при условии что смен стейтов не делается: если
- запаковать меши в 1 vbo
- текстуры в массивы/атласы
- переменные хранить в UBO/текстурах и передавать только смещение по которому данные находятся
- и шейдер ты не меняешь
>может, выложить тестбед, чтобы быстро собрать данные с разных железок у пользователей?
дописать немного надо, постараюсь)
_Wizard_
> Ну и опять же повторюсь - при условии что смен стейтов не делается: если
> - запаковать меши в 1 vbo
> - текстуры в массивы/атласы
> - переменные хранить в UBO/текстурах и передавать только смещение по которому
> данные находятся
> - и шейдер ты не меняешь
Скажи просто, AZDO
>#extension GL_EXT_bindable_uniform : enable
Что это древнее расширение эпохи динозавров делает в такой современной статье? В ядре OpenGL уже давно есть нормальные UBO.
Тема в архиве.