Я видел много вопросов, разбросанных по всему Интернету о разветвленности веток, и о том, как избежать этого. Однако даже после чтения десятков статей о том, как работает CUDA, , я не вижу, как избежать в большинстве случаев отклонения от ветки.. Прежде чем кто-нибудь скачет на меня с протянутыми когтями, позвольте мне описать, что я считаю "большинством дел".
Мне кажется, что большинство случаев расхождения ветвей связаны с рядом действительно различных блоков кода. Например, мы имеем следующий сценарий:
if (A):
foo(A)
else:
bar(B)
Если у нас есть два потока, которые сталкиваются с этим расхождением, поток 1 будет выполняться первым, пройдя путь A. После этого поток 2 примет путь B. Чтобы удалить расхождение, мы можем изменить вышеприведенный блок, чтобы читать как это
foo(A)
bar(B)
Предполагая, что безопасно вызывать foo(A)
в потоке 2 и bar(B)
в потоке 1, можно ожидать, что производительность улучшится. Однако здесь я вижу это:
В первом случае потоки 1 и 2 выполняются последовательно. Вызовите эти два тактовых цикла.
Во втором случае потоки 1 и 2 выполняют foo(A)
параллельно, затем выполняйте bar(B)
параллельно. Это по-прежнему выглядит как два такта, разница в том, что в первом случае, если foo(A)
включает чтение из памяти, я думаю, что поток 2 может начать выполнение во время этой задержки, что приводит к скрытию скрытия. Если это так, расходящийся код ветки быстрее.