用于并行和减少的 Vulkan 计算着色器

Vulkan compute shader for parallel sum reduction

我想实现这个算法 https://dournac.org/info/gpu_sum_reduction 在 Vulkan 的计算着色器中。在 OpenCL 中这很容易,因为我可以显式声明 哪些缓冲区是 __local,哪些是 __global。不幸的是,我似乎无法找到 Vulkan 中的任何此类机制。请更有经验的人给我举个例子,如何让这些东西在 Vulkan 中工作?

Vulkan 中的子组功能似乎相同。这是着色器调用可以在子组中协作的功能。

可能是这样的:

void main(){
    int partial_sum = subgroupAdd(arr[gl_GlobalInvocationID.x]);

    if (subgroupElect()) {
        atomicAdd(mem, partial_sum);
    }
}

你可以研究Subgroup Tutorial

那么你可以再次尝试通过简单的“正常”方式来解决它:

void main(){
    int partial_sum = 0;
    for( int i = 0; i < LOCAL_SIZE; ++i ){
        partial_sum += arr[gl_WorkGroupID.x * gl_WorkGroupSize.x + i]
    }

    atomicAdd(mem, partial_sum); // or perhaps without atomics by recursively reducing
}

与其说是“平行”,不如说是没有障碍。这只是衡量性能以找到最佳效果的问题,并且还可能取决于您假设输入数组有多大。

免责声明:我没有尝试过着色器,因此假设它们是一种伪代码并且可能存在错误。

也应该可以几乎逐字逐句地实现您的链接算法。计算 GLSL 中 __local 的等价物是 shared。 GLSL 中的工作组障碍是 memoryBarrierShared().