Module: Mesa Branch: main Commit: fc0aaa81eed4ea0e6e6577e068511fae07773461 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=fc0aaa81eed4ea0e6e6577e068511fae07773461
Author: Kenneth Graunke <[email protected]> Date: Mon Aug 21 18:55:13 2023 -0700 nir: Reduce the scope of shared memory barriers Originally written by Ian Romanick for the Intel backend, but ported to the new nir_opt_barrier_modes() common optimization pass. Ian's original explanation and commit message follows: Shared memory only exists within a workgroup, so synchronizing it beyond workgroup scope is nonsense. Basically every SPIR-V compiler generates operations like OpMemoryBarrier(/*Memory*/Device, /*Semantics*/AcquireRelease | WorkgroupMemory) This is suggested in numerous places, including https://github.com/KhronosGroup/GLSL/blob/master/extensions/khr/GL_KHR_vulkan_glsl.txt. Even Mesa's glsl_to_nir pass does this. This advice, which has been copy-and-pasted everywhere, is contrary to issue 13 in the original GL_ARB_compute_shader spec: "Since shared memory is only accessible to threads within a single work group, memoryBarrierShared() also only requires synchronization with other threads in the same work group." Reviewed-by: Alyssa Rosenzweig <[email protected]> Reviewed-by: Ian Romanick <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24842> --- src/compiler/nir/nir_opt_barriers.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/compiler/nir/nir_opt_barriers.c b/src/compiler/nir/nir_opt_barriers.c index 56e5f49140e..1566576ec2e 100644 --- a/src/compiler/nir/nir_opt_barriers.c +++ b/src/compiler/nir/nir_opt_barriers.c @@ -184,6 +184,16 @@ nir_opt_barrier_modes_impl(nir_function_impl *impl) nir_intrinsic_set_memory_modes(barrier, new_modes); progress = true; } + + /* Shared memory only exists within a workgroup, so synchronizing it + * beyond workgroup scope is nonsense. + */ + if (nir_intrinsic_execution_scope(barrier) == SCOPE_NONE && + new_modes == nir_var_mem_shared) { + nir_intrinsic_set_memory_scope(barrier, + MIN2(nir_intrinsic_memory_scope(barrier), SCOPE_WORKGROUP)); + progress = true; + } } nir_instr_worklist_destroy(barriers); @@ -193,7 +203,7 @@ nir_opt_barrier_modes_impl(nir_function_impl *impl) } /** - * Reduce barriers to remove unnecessary modes. + * Reduce barriers to remove unnecessary modes and scope. * * This pass must be called before nir_lower_explicit_io lowers derefs! * @@ -212,6 +222,9 @@ nir_opt_barrier_modes_impl(nir_function_impl *impl) * various shared memory operations. Image reads and writes do also exist, * but they are all on one side of the barrier, so it is a no-op for image * access. We can drop the image mode from the barrier in this case too. + * + * In addition, we can reduce the memory scope of shared-only barriers, as + * shared local memory only exists within a workgroup. */ bool nir_opt_barrier_modes(nir_shader *shader)
