Reduce barrier/collective execution floor - #1240
avinciguerra07 wants to merge 2 commits into
Conversation
Shrink the shmem_barrier_all/collective critical path on OFI manual-progress builds that have no on-node (XPMEM/CMA) shortcut, where the internal pSync reset was issued as a put-to-self over the fabric plus a wait for its own NIC writeback on every PE every collective. - collectives.c: replace the self-loopback pSync clear (put_scalar to shmem_internal_my_pe + SHMEM_WAIT_UNTIL == 0) with a local store plus an acquire-release fence at all 22 sync/broadcast/reduce/scan/fcollect sites. Each clear is preceded by a fully-draining counting wait, so the incoming call-ins are already drained and a local reset before the next reuse is race-free; remote ack/signal puts are unchanged. - transport_ofi.h: skip the progress-lock trylock/unlock in shmem_transport_probe() when running SHMEM_THREAD_SINGLE, and read the put error counter in shmem_transport_quiet() only when completions have stalled (success < cnt) instead of every spin, keeping error detection intact. Barrier microbenchmark (osu_oshm_barrier, 2 CN5000 nodes, OFI/opx) shows a ~15-40 percent reduction of the pure barrier floor at low-mid PE counts; gauss-legendre pi-benchmark output is bit-identical (total_hex_digits and spigot checks unchanged). Signed-off-by: Armando Vinciguerra <armando.vinciguerra@cornelisnetworks.com>
|
This changes a put to self with a CPU store. I do not understand why this should work. If other PEs modify the same location using atomics and the atomicity zone is using NIC atomics that might be cached in the NIC, then a CPU atomic will not work correctly. If the only remote operations are ordinary puts, then it could work. |
I was working on the assumption that the barrier makes the slot quiescent at clear time: the SHMEM_WAIT_UNTIL(pSync == N) above the clear has already drained all N call-ins for this round, and barrier semantics forbid any PE from issuing the next round's call-in until every PE has left this barrier (each waits for its ack). So between "count satisfied" and "next round's first atomic," no atomic is in flight against the cell, nothing races the store. But if I understand what you are saying, a NIC-atomic provider, "drained all call-ins" (completion-visible) does not guarantee the NIC has written the value back to host memory? This seems to work for ofi, but I might be breaking some other transport. Would it be alright if I gated it with something like this: static inline void Or something more conservative like an env variable and we have to manually enable it at config: --enable-host-atomic-psync-clear? |
|
That is indeed the issue I am worried about, you can't mix shmem atomics with loads, stores, or atomics in a different atomicity domain. The first idea only works if the psync is only used for barriers with the same arguments... I'd argue the performance of the active set versions is uninteresting, and the spec is broken anyway, since it specifies initializing the user supplied psync with load/store and then uses them with atomics. |
|
Well the exact wording is
Which at least suggests that you can alternate atomic and non-atomic accesses provided you can prove the accesses are not concurrent, which I think means potentially occurring in different orders In the case of barrier, the WAIT guarantees that clearing the psync doesn't occur until after all atomic updates are visible, and doing the clear before the downstream notifications guarantees that no future atomics will occur until the clear is done So I guess the change is OK. |
|
This also suggests that NIC atomics are not allowed to cache, which I find surprising. I wonder if that is true. |
I like this idea much better than mine. I will test it a little bit and if all goes well you should see a push with this implementation soon. |
The internal world barrier (shmem_internal_sync_tree over the dedicated shmem_internal_barrier_all_psync / shmem_internal_sync_all_psync arrays) runs over a constant tree topology with a fixed PE count, and its pSync slot is only ever incremented via atomic SUM call-ins. Rather than reset the slot to zero after every barrier -- which the prior change did with a local CPU store -- remember a running base and wait for base + delta, then advance the base. The slot is never written locally at all, so this is correct on every transport, including ones that apply AMOs in NIC-cached memory (addresses the review concern about mixing a CPU store with NIC-side atomics). The accumulate-rebase only applies to the two dedicated internal world pSync arrays where topology and PE count are constant; every other pSync (active-set/user-supplied, sub-world teams, sync_linear, dissem, and the broadcast/reduce/scan/collect handshakes) keeps the local-store clear. Validated correct with gauss-legendre -b30 at 64 PE and 256 PE on CN5000 (total_hex_digits=268435376, spigot rc=0, no NACKs); no 2-node barrier regression. The execution-floor benefit is expected to compound at large node/PE counts and remains to be confirmed at full scale. Signed-off-by: Armando Vinciguerra <armando.vinciguerra@cornelisnetworks.com>
Shrink the shmem_barrier_all/collective critical path, where the internal pSync reset was issued as a put-to-self over the fabric plus a wait for its own NIC writeback on every PE every collective.
collectives.c: replace the self-loopback pSync clear (put_scalar to shmem_internal_my_pe + SHMEM_WAIT_UNTIL == 0) with a local store plus an acquire-release fence at all 22 sync/broadcast/reduce/scan/fcollect sites. Each clear is preceded by a fully-draining counting wait, so the incoming call-ins are already drained and a local reset before the next reuse is race-free; remote ack/signal puts are unchanged.
transport_ofi.h: skip the progress-lock trylock/unlock in shmem_transport_probe() when running SHMEM_THREAD_SINGLE, and read the put error counter in shmem_transport_quiet() only when completions have stalled (success < cnt) instead of every spin, keeping error detection intact.
Barrier microbenchmark (osu_oshm_barrier) shows a ~15-40 percent reduction of the pure barrier.