Графический процессор работает с потоками по группам 32, называемым перекосами. Всякий раз, когда различные потоки в warp проходят через разные пути в коде, GPU должен запускать весь warp несколько раз, один раз для каждого пути кода.
Для решения этой проблемы, называемой расхождением warp, вы хотите упорядочить свои потоки, чтобы потоки в заданной деформации проходили как можно больше различных путей кода. Когда вы это сделали, вам в значительной степени просто нужно укусить пулю и принять потерю производительности, вызванную любой оставшейся деформой. В некоторых случаях, возможно, не все, что вы можете сделать, чтобы упорядочить свои потоки. Если это так, и если разные кодовые пути являются важной частью вашего ядра или общей рабочей нагрузки, задача может оказаться непригодной для графического процессора.
Не имеет значения как вы реализуете различные пути кода. if-else
, switch
, предикация (в PTX или SASS), таблицы ветвей или что-то еще - если дело доходит до потоков в warp, работающих на разных путях, вы получаете удар по производительности.
Также не имеет значения, сколько потоков проходит по каждому пути, а всего общее количество различных путей в деформации.
Здесь another answer на этом, что идет немного подробнее.
Это зависит от того, что каждая нить в warp обычно принимает разные пути из-за переключателя или у вас есть, например. один коммутатор, который намного более распространен, чем остальные. Шаблон определит, сколько разницы в деформации вы получаете. –
Как я знаю, коммутаторы, как правило, сопоставляются с инструкцией короткого перехода не как последовательность ifs. В C++ коммутатор обычно более эффективен, чем несколько операторов if. Я думаю, вам нужно исследовать отображение команд CUDA в этом случае до окончательного предложения. – geek
Что находится внутри каждого заявления 'case'? Это однолинейный? Или несколько строк кода? Проводка примера, вероятно, даст вам более конкретные ответы. – Pedro