Мне интересно, если в пределах одной волны / подгруппы (деформации?) Нам нужно вызвать 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 и изменить =
на +=