barrier synchronization
**Barrier Synchronization** is the **parallel programming primitive where all participating threads or processes must arrive at the barrier point before any can proceed past it — ensuring that all work before the barrier is complete and visible to all participants before any post-barrier computation begins, making barriers the most fundamental synchronization mechanism in bulk-synchronous parallel programming and a primary source of performance overhead when load is imbalanced**.
**Why Barriers Are Needed**
Many parallel algorithms have phases: all threads compute, then all threads exchange data, then all threads compute again. The phase transitions require barriers — without them, a fast thread might start reading data that a slow thread hasn't finished writing. Example: iterative solvers where each iteration depends on the previous iteration's complete results.
**Barrier Implementations**
- **Centralized Barrier (Counter-Based)**: A shared counter incremented atomically by each arriving thread. The last thread (counter == N) resets the counter and releases all waiting threads. Simple but creates a contention bottleneck on the counter for large N.
- **Sense-Reversing Barrier**: Each thread toggles a local "sense" flag on each barrier. The centralized counter releases when all arrive, and the sense alternation prevents races between consecutive barriers. Fixes the re-use bug of naive counter barriers.
- **Tree Barrier (Tournament)**: Threads are organized in a binary tree. At each level, a thread waits for its sibling before passing to the parent level. When the root arrives, the release signal propagates back down the tree. Latency: O(log N). Avoids single-point contention. Used in MPI implementations.
- **Butterfly Barrier**: Each thread exchanges "arrived" notifications with partners at distances 1, 2, 4, 8, ... in log₂(N) rounds (similar to recursive doubling). Every thread knows all others have arrived after log₂(N) communication rounds. Distributed — no central bottleneck.
- **Hardware Barrier**: Some HPC interconnects (Cray Aries, Fujitsu Tofu) provide hardware barrier support — a dedicated signal network that propagates barrier completion in constant time or O(log N) hardware hops, regardless of P.
**GPU Barriers**
- **__syncthreads()**: Block-level barrier in CUDA. All threads in the thread block must reach this point. Compiles to a hardware barrier instruction on the SM. Extremely fast (~20 cycles) because it operates within a single SM.
- **cooperative_groups::this_grid().sync()**: Grid-level barrier (CUDA 9+). All blocks in the kernel synchronize. Requires cooperative launch and all blocks to be resident simultaneously.
- **No Warp-Level Barrier Needed**: Threads within a warp execute in lockstep (SIMT) — they are implicitly synchronized at every instruction. __syncwarp() is used after warp-level programming with independent thread scheduling (Volta+).
**Performance Impact**
Barrier cost = max(arrival_time) + synchronization_overhead. If one thread takes 2x longer than others, all threads wait for the slowest — the barrier converts the slowest thread's excess time into idle time for all other threads. This is why load balancing and barrier frequency reduction are critical for parallel performance.
Barrier Synchronization is **the phase boundary of parallel execution** — the point where all parallel work converges, making barriers simultaneously the most essential synchronization mechanism and the most visible source of parallel overhead when workload balance is imperfect.