Волна / подгруппа нуждается в синхронизации для общих переменных?
Мне интересно, если в той же волне / подгруппе (деформации?) Нам нужно позвонить memoryBarrierShared
а также barrier
синхронизировать общую переменную? В NVIDIA я думаю, что в этом нет необходимости, но я не знаю для других IHV.
РЕДАКТИРОВАТЬ: избирательный бюллетень
Поскольку я говорю о волне / подгруппе, я говорю о ARB_shader_ballot
расширение.
Допустим, у нас есть такой код (1):
shared uint s_data[128];
uint tid = gl_GlobalInvocationID.x;
// initialization of some s_data
memoryBarrierShared();
barrier();
if(tid < gl_SubGroupSizeARB) {
for(uint i = gl_SubGroupeSizeARB; i > 0; i>>=1)
s_data[tid] += s_data[tid + i];
}
По мне, этот код не является правильным. Правильный, согласно спецификации, будет (2):
if(tid < gl_SubGroupSizeARB) {
for(uint i = gl_SubGroupeSizeARB; i > 0; i>>=1) {
s_data[tid] += s_data[tid + i];
memoryBarrierShared();
barrier();
}
}
Однако, поскольку вызовы выполняются параллельно в волне / подгруппе, barrier
функция кажется бесполезной: эта должна быть правильной и быстрее второй (3):
if(tid < gl_SubGroupSizeARB) {
for(uint i = gl_SubGroupeSizeARB; i > 0; i>>=1) {
s_data[tid] += s_data[tid + i];
memoryBarrierShared();
}
}
Однако, поскольку нам не нужно barrier
Интересно, если (1) правильно, даже если это маловероятно для меня, а если нет, если (3) правильно (это означает, что мое понимание верно)
РЕДАКТИРОВАТЬ: int к uint и изменить =
в +=
1 ответ
Модель исполнения, используемая OpenGL и Vulkan в отношении вычислительных шейдеров, на самом деле не признает концепцию "волны". У него есть концепция рабочей группы, но это не одно и то же. Рабочая группа может быть намного больше, чем "волна" GPU, а для небольших рабочих групп несколько рабочих групп могут работать на одной "волне" GPU.
Как таковые, эти спецификации не делают никаких заявлений о поведении какой-либо из ее функций по отношению к "волне" (за исключением функций голосования шейдеров). Таким образом, если вы хотите синхронизацию, которая, согласно стандарту, будет работать во всех соответствующих реализациях, вы должны вызывать обе функции в соответствии с требованиями стандарта.
Даже с ARB_shader_ballot
, его поведение не изменяет модель исполнения шейдеров. Это позволяет только перекрестную связь между подгруппами, и только через явные механизмы, которые это обеспечивает.
Модель выполнения и модель памяти для вызовов шейдеров такова, что они неупорядочены относительно друг друга, если вы явно не упорядочите их с барьерами.