Расхождение в ветвях, CUDA и Kinetic Monte Carlo
================================================

Итак, у меня есть код, который использует Kinetic Monte Carlo на решетке, чтобы что-то имитировать. Я использую CUDA для запуска этого кода на моем GPU (хотя я считаю, что тот же вопрос относится и к OpenCl).

Это означает, что я делю свою решетку на маленькие подрешетки, и каждый поток воздействует на одну из них. Так как я делаю KMC, каждый поток имеет этот код:

A отличается для разных потоков, так же как и вы, а 100 - просто случайное число. В коде это может быть 1000 или даже 10000.

Итак, не будет ли у нас дивергенции ветвей, когда придет время для прохождения потока, если? Насколько это может повлиять на производительность? Я знаю, что ответ зависит от кода внутри предложения if, но как это масштабируется, когда я добавляю все больше и больше потоков?

Любая ссылка на то, как я могу оценить потери / выгоды в производительности, также будет приветствоваться.

Спасибо!

 которые называются деформациями. Дивергенция может произойти только в пределах основы. Итак, если вы можете расположить свои темы таким образом, чтобы`if` Состояние оценивается одинаково во всем варпе, дивергенции нет.

Когда есть расхождение в`if`концептуально графический процессор просто игнорирует результаты и запросы памяти потоков, в которых`if` состояние было ложным.

Итак, скажем, что`if` оценивает`true` для 10 нитей в конкретном перекосе. Пока внутри`if`потенциальная вычислительная производительность деформации уменьшена со 100% до 10/32 * 100 = 31%, поскольку 22 потока, которые были отключены`if` могли бы делать работу, но сейчас занимают место в варпе.

Однажды выходя из`if`отключенные потоки снова включаются, и деформация продолжается со 100% -ной потенциальной производительностью вычислений.

`if-else` ведет себя во многом так же. Когда деформация достигает`else`потоки, которые были включены в`if` становятся отключенными, а те, которые были отключены, становятся включенными.

В`for` В цикле, который зацикливается разное количество раз для каждого потока в деформации, потоки отключаются, поскольку их число итераций достигает своих заданных номеров, но деформация в целом должна продолжать цикл до тех пор, пока не будет достигнут поток с наибольшим числом итераций.

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

Итак, теперь у вас, вероятно, достаточно обзора, чтобы суметь сделать достаточно здравые суждения о том, насколько расхождение деформации повлияет на вашу производительность. Худший случай, когда активен только один поток в деформации. Тогда вы получите 1/32 = 3,125% от потенциала производительности вычислений. Лучший случай - 31/32 = 96,875%. Для`if` это совершенно случайно, вы получаете 50%. И, как уже упоминалось, производительность памяти зависит от изменения количества требуемых транзакций памяти.