gl_SemanticsRelaxed、gl_SemanticsRelease 和 gl_SemanticsAcquire 等 vulkan 内存语义标志在 Vulkan GLSL 中有什么作用?

what do vulkan memory semantic flags like gl_SemanticsRelaxed, gl_SemanticsRelease, and gl_SemanticsAcquire do in Vulkan GLSL?

我试图弄清楚以下代码中的原子存储函数是如何工作的,它们依赖于 GL_KHR_memory_scope_semantics

 uint exclusive_prefix = 0;
    if (local_ix == 31) {
        atomicStore(work_buf[my_tile * 4 + 2], total, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
        uint flag = FLAG_AGGREGATE_READY;
        if (my_tile == 0) {
            atomicStore(work_buf[my_tile * 4 + 3], total, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
            flag = FLAG_PREFIX_READY;
        }
        atomicStore(work_buf[my_tile * 4 + 1], flag, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelease);
        if (my_tile != 0) {
            // step 4: decoupled lookback
            uint look_back_ix = my_tile - 1;
            while (true) {
                flag = atomicLoad(work_buf[look_back_ix * 4 + 1], gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquire);
                if (flag == FLAG_PREFIX_READY) {
                    uint their_prefix = atomicLoad(work_buf[look_back_ix * 4 + 3], gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
                    exclusive_prefix = their_prefix + exclusive_prefix;
                    break;
                } else if (flag == FLAG_AGGREGATE_READY) {
                    uint their_agg = atomicLoad(work_buf[look_back_ix * 4 + 2], gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
                    exclusive_prefix = their_agg + exclusive_prefix;
                    look_back_ix--;
                }
                // else spin
            }

            // step 5: compute inclusive prefix
            uint inclusive_prefix = exclusive_prefix + total;
            shared_prefix = exclusive_prefix;
            atomicStore(work_buf[my_tile * 4 + 3], inclusive_prefix, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
            flag = FLAG_PREFIX_READY;
            atomicStore(work_buf[my_tile * 4 + 1], flag, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelease);
        }
    }

实际上是在努力完成。但是我找不到任何提及,例如 gl_SemanticsRelaxed 甚至意味着什么。我能找到的最接近的是在 GL_KHR_memory_scope_semantics 规范中说的,但它甚至只提到一次“放松”这个词,这只是为了说明 gl_SemanticsRelaxed 存在。

事实上,规范文件似乎只是间接描述了gl_SemanticsReleasegl_SemanticsAcquire可能做什么,而完全忽略了其他5种内存语义类型.

 * "Release/Acquire semantics" are used to guarantee ordering between
    an atomic or barrier and other memory operations that occur before
    or after it in program order, as observed by other invocations.

这是明显语义类型的列表:

        const int gl_SemanticsRelaxed         = 0x0;
        const int gl_SemanticsAcquire         = 0x2;
        const int gl_SemanticsRelease         = 0x4;
        const int gl_SemanticsAcquireRelease  = 0x8;
        const int gl_SemanticsMakeAvailable   = 0x2000;
        const int gl_SemanticsMakeVisible     = 0x4000;
        const int gl_SemanticsVolatile        = 0x8000;

充其量我可以猜到它的意思,但它在上下文中没有意义。我假设 relaxed 意味着你可以重新排列原子,直到获取而不关心,但然后它们在获取之前释放,这对我来说没有意义。

这些原子基本上是在轮询其他工作组是否完成了前缀和例程中的工作,完整代码在这里:https://github.com/linebender/piet-gpu/blob/prefix/piet-gpu-hal/examples/shader/prefix.comp paper which describes algorithm here: https://research.nvidia.com/publication/single-pass-parallel-prefix-scan-decoupled-look-back

您链接到的规范似乎很清楚:

gl_StorageSemantics* and gl_Semantics* values should be bitwise ORed together to generate the SPIR-V Semantics enums

并且它还指定了 GL 原子函数如何映射到 SPIR-V atomic operations. So the answers you seek are in the SPIR-V specification. And the deep details are defined by the Vulkan memory model, appendix B of the Vulkan specification