subgroupMemoryBarrier полезность - PullRequest
0 голосов
/ 07 января 2019

Этот вопрос похож на Полезность GLSL memoryBarrierShared ()? .

Однако мне интересно, когда мы должны использовать subgroupMemoryBarrier и аналогичные функции, поскольку subgroupBarrier выполняет как выполнение, так и барьер памяти. Для функции memoryBarrier я понимаю, потому что функция barrier не выполняет барьер памяти. поэтому вы должны использовать оба:

memoryBarrier(); // memoryBarrierShared, Buffer, Image...
barrier();

Но я не знаю, когда я смогу использовать subgroupMemoryBarrier, потому что это уже сделано subgroupBarrier.

Расширение GL_KHR_shader_subgroup

Функция subgroupBarrier () обеспечивает выполнение всех активных вызовов в пределах Подгруппа должна выполнить эту функцию, прежде чем любой из них сможет продолжить выполнение и результаты любых хранилищ памяти, выполненных с использованием связного переменные, выполненные до вызова, будут видны любому будущему согласованный доступ к той же памяти, выполняемый любым другим вызовом шейдера в той же подгруппе.

Я не думаю, что они сделали эти функции, если они бесполезны. Поэтому мне интересно, когда мы должны их использовать?

Это потому, что в подгруппе предполагается, что они работают параллельно, поэтому вы можете просто выполнить subgroupMemoryBarrier. Но в этом случае, когда вам нужно использовать subgroupBarrier?

1 Ответ

0 голосов
/ 07 января 2019

Здесь есть два очень разных поведения, MemoryBarrier() и Barrier(). У них обоих есть барьер в названии, но на самом деле они имеют совершенно разные эффекты.

Барьеры памяти предназначены для обеспечения некоторого относительного упорядочения памяти в пределах одного потока выполнения (например, одного вычислительного рабочего элемента). Доступ к памяти до того, как барьер должен быть завершен, до того, как доступ к барьеру будет разрешен. В традиционном коде ЦП это полезно для таких вещей, как блокировки - например, убедитесь, что замок успешно снят и записан в память, прежде чем касаться структуры, которую он защищал. На выполнение потоков внутри подгруппы относительно друг друга не влияют, так что вы можете запускать вещи параллельно, не истощая канал, и один поток в подгруппе может запускать код до барьера памяти, а другой - после кода барьер памяти.

Полные барьеры предназначены для выравнивания исполнения в подгруппе. Ни один поток в подгруппе не может запустить какой-либо код после барьера, пока все потоки не достигнут барьера, что неявно означает, что они также обеспечивают семантику барьера памяти. Это то, что вам нужно, когда вы хотите положиться на алгоритмы без блокировки, когда одному потоку нужно делать предположения о том, куда достиг другой поток в подгруппе. Например, ожидание потока для localInvocation 0 для заполнения локальной памяти.

...