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

Мне интересно, если в той же волне / подгруппе (деформации?) Нам нужно позвонить 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, его поведение не изменяет модель исполнения шейдеров. Это позволяет только перекрестную связь между подгруппами, и только через явные механизмы, которые это обеспечивает.

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

Другие вопросы по тегам