像 gl_SemanticsRelaxed、gl_SemanticsRelease 和 gl_SemanticsAcquire 这样的 vulkan 内存语义标志在 Vulkan GLSL 中的作用是

Posted

技术标签:

【中文标题】像 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_SemanticsRelaxed、gl_SemanticsRelease 和 gl_SemanticsAcquire 这样的 vulkan 内存语义标志在 Vulkan GLSL 中的作用是什么? 【发布时间】:2021-05-14 19:22:21 【问题描述】:

我试图弄清楚以下代码中的原子存储功能是如何工作的,它们依赖于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

【问题讨论】:

khronos.org/registry/vulkan/specs/1.2-extensions/html/… 和 khronos.org/registry/spir-v/specs/unified1/… 似乎提供了一些文档 【参考方案1】:

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

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

它还指定了 GL 原子函数如何映射到 SPIR-V atomic operations。所以你寻求的答案在the SPIR-V specification。深层细节由 Vulkan 内存模型定义,appendix B of the Vulkan specification。

【讨论】:

以上是关于像 gl_SemanticsRelaxed、gl_SemanticsRelease 和 gl_SemanticsAcquire 这样的 vulkan 内存语义标志在 Vulkan GLSL 中的作用是的主要内容,如果未能解决你的问题,请参考以下文章

我可以像在(mapbox-gl-js 文档)中那样使用 react-map-gl 添加 GeoJSON 行吗?

如何像 GL_REPEAT 一样重复纹理贴图?

使用单通道纹理(OpenGL 2)?

何时在 OS X 上使用 OpenGL 与 GL

GL_TEXTURE_3D 是啥意思?

应该是每个纹理单元应用glEnable(GL_TEXTURE_2D)