Волна / подгруппа нуждается в синхронизации для общих переменных? - PullRequest
0 голосов
/ 03 января 2019

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

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

Модель исполнения, используемая OpenGL и Vulkan в отношении вычислительных шейдеров, на самом деле не признает концепцию «волны». У него есть концепция рабочей группы, но это не одно и то же. Рабочая группа может быть намного больше, чем "волна" графического процессора, а для небольших рабочих групп несколько рабочих групп могут выполняться на одной "волне" графического процессора.

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

Даже с ARB_shader_ballot его поведение не изменяет модель исполнения шейдеров. Он допускает только перекрестную связь между подгруппами, и только через явные механизмы, которые он предоставляет.

Модель выполнения и модель памяти для вызовов шейдеров такова, что они неупорядочены относительно друг друга, если вы явно не упорядочите их с барьерами.

...