Семантика барьера () в вычислительном шейдере opengl
Допустим, у меня есть вычислительный шейдер opengl, написанный на GLSL, работающий на NVidia Geforce 970.
В начале шейдера единственный вызов записывает "объект буфера хранилища шейдеров" (SSBO).
Затем я запускаю подходящий барьер, такой как memoryBarrier() в моем GLSL.
Затем я читаю из памяти, записанной на первом шаге, в каждом вызове.
Будет ли эта первая запись видима для всех вызовов в текущей вычислительной операции?
На https://www.khronos.org/opengl/wiki/Memory_Model Хронос говорит:
"Используйте согласованный и соответствующий вызов memoryBarrier* или groupMemoryBarrier, если вы используете механизм, подобный барьеру, для синхронизации между вызовами".
Я почти уверен, что это возможно для синхронизации в рабочей группе. Но работает ли он для всех вызовов в каждой рабочей группе, во всей вычислительной операции?
Я не уверен, как запланирован весь набор рабочих групп. Я ожидал бы, что они будут работать последовательно, делая невозможной синхронизацию, о которой я спрашиваю?
1 ответ
Но работает ли он для всех вызовов в каждой рабочей группе, во всей вычислительной операции?
Нет. Объем barrier
явно в рабочей группе. И вы не можете видеть операции, которые вы еще не гарантировали. Порядок выполнения рабочих групп по отношению друг к другу не определен, поэтому вы не знаете, была ли еще одна рабочая группа выполнена.
То, что вы хотите, на самом деле не возможно. Вместо этого вам нужно изменить работу ваших шейдеров, чтобы рабочие группы не зависели друг от друга. В этом случае вы можете заставить каждую рабочую группу выполнить это вычисление. И вместо того, чтобы хранить его в глобальной памяти через SSBO, сохраните результат в shared
переменная.
Да, вы будете вычислять одно и то же значение в каждой группе. Но это даст лучшую производительность, чем когда все эти рабочие группы ждут в одной рабочей группе. Тем более, что это не то, что вы действительно можете сделать.