Мне интересно, как лучше интегрировать функцию динамического цикла в шейдер?
Во-первых, кажется, что динамические массивы невозможны. Итак, лучше ли создавать массив максимального размера и заполнять только его часть или определять массивы с заранее заданными размерами?
Тогда, как лучше всего перебрать этот массив?
Лучше использовать развернутый цикл или динамический цикл для чего-то между 4 и 128 итерациями? Я также видел, что можно развернуть его до максимального заранее определенного числа итераций, а затем остановить его с помощью условия, такого как if (i == myCurrentMaximumIterationNumber)
.
Ответы:
Шейдерные компиляторы чрезвычайно агрессивны в отношении развертывания, поскольку в ранних версиях HW часто не было управления потоком данных, и стоимость последних HW может варьироваться. Если у вас есть тест, с которым вы активно тестируете тесты, и целый ряд соответствующего оборудования, то попробуйте что-нибудь посмотреть, что произойдет. Ваш динамический цикл более поддается вмешательству разработчика, чем статический цикл, но предоставление его компилятору по-прежнему будет хорошим советом, если у вас нет доступного эталонного теста. С эталоном, исследование стоит (и весело).
Кстати, самая большая потеря динамического цикла на графическом процессоре состоит в том, что отдельные «потоки» в волновом фронте / деформации заканчиваются в разное время. Потоки, которые останавливаются позже, вынуждают все те, которые заканчиваются рано, выполнять NOP.
Вложенные циклы должны быть тщательно продуманы: я реализовал блочный энтропийный декодер, который кодировал серии нулей (для JPEG-подобного сжатия). Естественная реализация заключалась в том, чтобы декодировать прогоны в тесном внутреннем цикле - что означало, что только один поток делал успехи; сгладив цикл и явно проверив в каждом потоке, декодирует ли он текущий цикл или нет, я сохранил все потоки активными в цикле фиксированной длины (декодированные блоки были одинакового размера). Если бы потоки были похожи на потоки ЦП, изменение было бы ужасным, но на GPU, на котором я работал, я получил 6-кратное увеличение производительности (что было все еще ужасно - не было достаточно блоков, чтобы поддерживать занятость GPU - но это было доказательство концепции).
источник