wave /子组是否需要同步共享变量?

时间:2019-01-03 09:01:36

标签: opengl glsl vulkan

我想知道是否在同一wave /子组(扭曲)中,我们需要调用memoryBarrierSharedbarrier来同步共享变量?我认为在NVIDIA中这不是必需的,但我不知道其他IHV。

编辑:投票

因为我在谈论wave /子组,所以我在谈论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();
    }
}

但是,由于调用是在wave /子组中并行运行的,因此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)是否正确(那意味着我理解是正确的)

EDIT:将int更改为uint,然后将=更改为+=

1 个答案:

答案 0 :(得分:3)

OpenGL和Vulkan关于计算着色器共享的执行模型并没有真正认识到“波动”的概念。它具有工作组的概念,但这不是一回事。一个工作组可能比GPU“波形”大得多,对于小型工作组,多个工作组可能在同一GPU“波形”上执行。

因此,这些规范未声明其任何功能相对于“波动”的行为(着色器选票功能除外)。因此,如果您希望标准说明的同步将在所有符合要求的实现上都可以使用,则必须按标准规定调用这两个函数。

即使使用ARB_shader_ballot,其行为也不会修改着色器的执行模型。它仅允许子组之间的交叉通信,并且只能通过其提供的显式机制进行

着色器调用的执行模型和内存模型是,它们彼此之间是无序的,除非您明确地将它们与障碍对齐。