Vulkan compute shader for parallel sum reduction

Viewed 659

I want to implement this algorithm https://dournac.org/info/gpu_sum_reduction in Vulkan's compute shader. In OpenCL it would be easy because I can explicitly declare what buffers are __local and which are __global. Unfortunately, I can't seem to find any such mechanisms in Vulkan. Could somebody more experienced, show me an example, how to get such things working in Vulkan, please?

1 Answers

Subgroups in Vulkan seem equivalent functionality. It is a functionality where the shader invocations can cooperate in the subgroup.

Maybe something like:

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

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

You could study the Subgroup Tutorial.

Then again you could just try going about it the "normal" way by simply:

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
}

It is not so much "parallel", but then again needs no barriers. It is just a matter of measuring performance to find what works best, and also might depend how large do you assume the input arrays are.

Disclaimer: I have not tried the shaders, so assume they are kind of a pseudocode and can have bugs.

It should also be possible to implement your linked algorithm nearly verbatim. The equivalent to __local in compute GLSL is shared. The workgroup barrier in GLSL is memoryBarrierShared().

Related