Ответ 1
Настройка текстуры на GPU занимает некоторое время процессора, но она достаточно мала по сравнению с фактической стоимостью batch. Что еще более важно, он не должен иметь никакого влияния на фактическое выполнение шейдера, если шейдер никогда не ссылается на него.
Теперь можно обрабатывать ветвление тремя способами:
Прежде всего, если условие ветвления всегда будет одним и тем же (если оно зависит только от констант времени компиляции), то одна сторона ветки может быть полностью развернута. Во многих случаях может быть предпочтительнее компилировать несколько версий вашего шейдера, если это позволяет устранить значительные ветки таким образом.
Второй метод заключается в том, что шейдер может оценивать обе стороны ветки, а затем выбирать правильный результат на основе условного, все без фактического разветвления (он делает это арифметически). Это лучше всего, когда код в ветки невелик.
И, наконец, он может использовать инструкции ветвления. Прежде всего инструкции ветки имеют скромные затраты на подсчет команд. И тогда есть трубопровод. X86 имеет длинный последовательный конвейер, который вы можете легко остановить. Графический процессор имеет совершенно другой параллельный конвейер.
GPU оценивает группы фрагментов (пикселей) параллельно, выполняя программу фрагмента один раз для нескольких фрагментов за раз. Если все фрагменты в группе занимают одну и ту же ветку, тогда у вас есть только стоимость выполнения этой ветки. Если они берут две (или более) ветки, то шейдер должен выполняться несколько раз для этой группы фрагментов, чтобы покрыть все ветки.
Поскольку группы фрагментов имеют экранную локальность, это помогает, если ваши ветки имеют сходную локальность на экране. См. Эту диаграмму:
http://http.developer.nvidia.com/GPUGems2/elementLinks/34_flow_control_01.jpg
Теперь шейдерный компилятор, как правило, очень хорошо подходит для выбора того, какой из последних двух методов использовать (для первого метода компилятор будет встроен для вас, но вам нужно сделать несколько версий шейдеров самостоятельно). Но если вы оптимизируете производительность, полезно увидеть фактический вывод компилятора. Для этого используйте fxc.exe
в утилитах DirectX SDK с параметром /Fc <file>
, чтобы получить представление разборки скомпилированного шейдера.
(Поскольку это рекомендация по производительности: не забудьте всегда измерять производительность, выяснить, какие ограничения вы нажимаете, а затем беспокоиться об оптимизации. Нет смысла оптимизировать ваши ветки шейдера, если вы привязываетесь к текстуре, для пример.)
Дополнительная ссылка: Графики GPU 2: Глава 34. Идиомы управления потоком GPU.