首页 > 解决方案 > 像 gl_SemanticsRelaxed、gl_SemanticsRelease 和 gl_SemanticsAcquire 这样的 vulkan 内存语义标志在 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;

充其量我可以猜到它的含义,但在上下文中没有意义。我认为放松意味着您可以重新排列原子直到获得而不在乎,但是然后它们在获得之前释放,这对我来说没有意义。

这些原子基本上轮询其他工作组,如果他们在前缀和例程中完成了他们的工作,完整代码在这里:https ://github.com/linebender/piet-gpu/blob/prefix/piet-gpu-hal/examples/ 在此处描述算法的shader/prefix.comp论文: https ://research.nvidia.com/publication/single-pass-parallel-prefix-scan-decoupled-look-back

标签: gpuglslatomicgpgpuvulkan

解决方案


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

gl_StorageSemantics* 和 gl_Semantics* 值应该按位或一起生成 SPIR-V Semantics 枚举

它还指定了 GL 原子函数如何映射到SPIR-V 原子操作。因此,您寻求的答案在SPIR-V 规范中。深层细节由 Vulkan 内存模型、Vulkan 规范的附录 B 定义


推荐阅读