Цикл производительности в шейдере

11

Мне интересно, как лучше интегрировать функцию динамического цикла в шейдер?

Во-первых, кажется, что динамические массивы невозможны. Итак, лучше ли создавать массив максимального размера и заполнять только его часть или определять массивы с заранее заданными размерами?

Тогда, как лучше всего перебрать этот массив?

Лучше использовать развернутый цикл или динамический цикл для чего-то между 4 и 128 итерациями? Я также видел, что можно развернуть его до максимального заранее определенного числа итераций, а затем остановить его с помощью условия, такого как if (i == myCurrentMaximumIterationNumber).

Мат
источник
2
Что вы пытаетесь сделать с массивом и циклом? Я спрашиваю, потому что это как-то звучит для меня как проблема XY . Поскольку лучший способ использовать условия и циклы в графическом процессоре - это воздерживаться от их использования, может быть, есть даже лучшие способы вместо использования массивов и циклов в вашем случае.
Nero
Я реализую эффект подповерхностного рассеяния на экране, который в настоящее время работает. Но у меня есть некоторые сомнения относительно того, как я использую ядро ​​в зависимости от производительности. Я решил сделать максимальный размер массива и заполнить только часть и использовать динамический цикл с динамическим числом итераций, который связан с используемым в настоящее время содержимым массива. Я думаю, что есть вещи, которые нужно делать или знать, например, при программировании шейдеров в соответствии с характеристиками. И, на мой взгляд, циклы - это общая тема производительности, которая может следовать некоторым правилам и, возможно, «хорошим практикам», но я не нашел хорошего ответа по этому поводу.
Мат

Ответы:

6

Шейдерные компиляторы чрезвычайно агрессивны в отношении развертывания, поскольку в ранних версиях HW часто не было управления потоком данных, и стоимость последних HW может варьироваться. Если у вас есть тест, с которым вы активно тестируете тесты, и целый ряд соответствующего оборудования, то попробуйте что-нибудь посмотреть, что произойдет. Ваш динамический цикл более поддается вмешательству разработчика, чем статический цикл, но предоставление его компилятору по-прежнему будет хорошим советом, если у вас нет доступного эталонного теста. С эталоном, исследование стоит (и весело).

Кстати, самая большая потеря динамического цикла на графическом процессоре состоит в том, что отдельные «потоки» в волновом фронте / деформации заканчиваются в разное время. Потоки, которые останавливаются позже, вынуждают все те, которые заканчиваются рано, выполнять NOP.

Вложенные циклы должны быть тщательно продуманы: я реализовал блочный энтропийный декодер, который кодировал серии нулей (для JPEG-подобного сжатия). Естественная реализация заключалась в том, чтобы декодировать прогоны в тесном внутреннем цикле - что означало, что только один поток делал успехи; сгладив цикл и явно проверив в каждом потоке, декодирует ли он текущий цикл или нет, я сохранил все потоки активными в цикле фиксированной длины (декодированные блоки были одинакового размера). Если бы потоки были похожи на потоки ЦП, изменение было бы ужасным, но на GPU, на котором я работал, я получил 6-кратное увеличение производительности (что было все еще ужасно - не было достаточно блоков, чтобы поддерживать занятость GPU - но это было доказательство концепции).

Даниэль М Гессель
источник