intel/compiler: Use nir_opt_uniform_atomics()
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 16 Mar 2022 10:06:22 +0000 (03:06 -0700)
committerMarge Bot <emma+marge@anholt.net>
Sat, 26 Mar 2022 00:28:19 +0000 (00:28 +0000)
commit823745dc27d87c79542fa402dde743a7061c6448
treed8faab814be9bde7aa6241f45c508156121fe9fe
parent49ef23f4a681e9132a13e4ef366b0641b1c1fe5e
intel/compiler: Use nir_opt_uniform_atomics()

In general, an atomic intrinsic may perform separate atomics for every
enabled SIMD channel, as each channel may operate on different memory.

However, an extremely common case is for all channels to access the same
memory location.  In this case, we can simply perform a reduction/scan
across the subgroup, and perform one atomic for the whole subgroup,
rather than one per channel.  For example, if an intrinsic says to take
the minimum value of the existing memory and the value in each channel,
we can do a thread-local minimum of all enabled channels, then do a
single atomic to take the minimum of that and the existing memory.

Our hardware doesn't optimize the case where multiple channels ask for
atomics on the same memory location; it assumes the compiler will do so.

nir_opt_uniform_atomics() uses divergence analysis to detect this case,
adds the necessary subgroup operations, and moves the atomic inside a
conditional that disables all but a single invocation.  It even detects
cases where the shader code already performs this kind of optimization,
and avoids doing it a second time.

This may not be the optimal solution for us.  In the backend, we could
detect this case and emit send(1) instructions with NoMask, rather than
generating if...send(16)...endif, and a lot of unnecessary ALU ops.  But
it's simple to do, reuses the same path as ACO, and still provides most
of the benefit by cutting up to 16x atomics down to a single atomic,
which is more merciful to the memory bus.

Improves performance of Shadow of the Tomb Raider by 5.5% on XeHP.

Improves performance of a customer-internal benchmark on XeHP at
3840x2160 and low settings by approximately 30%.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Caio Oliveira <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15484>
src/intel/compiler/brw_nir.c