Ответ 1
Вы предполагаете (по крайней мере, это пример, который вы даете, и единственную ссылку, которую вы делаете), что единственный способ избежать разветвления ветвей - разрешить всем потокам выполнять весь код.
В этом случае я согласен, что не так много.
Однако, избегая расхождения ветвей, возможно, больше связано с реструктуризацией алгоритма на более высоком уровне, чем просто добавление или удаление некоторых операторов if и обеспечение "безопасного" кода во всех потоках.
Я приведу один пример. Предположим, я знаю, что нечетные потоки должны обрабатывать синий компонент пикселя, и даже потоки должны обрабатывать зеленый компонент:
#define N 2 // number of pixel components
#define BLUE 0
#define GREEN 1
// pixel order: px0BL px0GR px1BL px1GR ...
if (threadIdx.x & 1) foo(pixel(N*threadIdx.x+BLUE));
else bar(pixel(N*threadIdx.x+GREEN));
Это означает, что каждый альтернативный поток принимает заданный путь, будь то foo
или bar
. Итак, теперь мой warp занимает в два раза больше времени.
Однако, если я изменил свои пиксельные данные так, чтобы цветовые компоненты были смежными, возможно, в кусках 32 пикселя: BL0 BL1 BL2... GR0 GR1 GR2...
Я могу написать аналогичный код:
if (threadIdx.x & 32) foo(pixel(threadIdx.x));
else bar(pixel(threadIdx.x));
По-прежнему кажется, что у меня есть возможность расхождения. Но так как расхождение происходит на границах деформации, то деформация дает либо путь if
, либо путь else
, поэтому фактическая дивергенция не возникает.
Это тривиальный пример и, вероятно, глупый, но он иллюстрирует, что могут быть способы работы с расхождением warp, которые не связаны с запуском всего кода всех расходящихся путей.