atomic operations parallel
**Atomic Operations** are the **hardware-guaranteed indivisible memory operations that read-modify-write a memory location as a single uninterruptible step — providing the fundamental building block for lock-free synchronization, concurrent data structures, and parallel coordination without the overhead and deadlock risk of traditional mutex-based locking**.
**Why Atomics Are Necessary**
Consider a simple counter incremented by two threads: `count = count + 1`. This compiles to three operations: load count, add 1, store count. If two threads execute this interleaved, both may load the same value, both add 1, and both store — resulting in count incremented by 1 instead of 2 (lost update). An atomic increment executes all three steps as one indivisible operation, guaranteeing correctness.
**Core Atomic Instructions**
- **Compare-And-Swap (CAS)**: `CAS(addr, expected, desired)` — atomically: if *addr == expected, set *addr = desired and return true; else return false. The universal building block for lock-free algorithms. Any other atomic operation can be built from CAS in a retry loop.
- **Fetch-And-Add (FAA)**: `FAA(addr, value)` — atomically adds value to *addr and returns the old value. Directly supported in hardware (x86 LOCK XADD, CUDA atomicAdd). More efficient than CAS loop for simple aggregation.
- **Exchange (Swap)**: `XCHG(addr, value)` — atomically writes value and returns the old content. Used for spinlock acquisition.
- **Load-Link / Store-Conditional (LL/SC)**: ARM and RISC-V alternative to CAS. LDXR loads a value and sets a hardware reservation. STXR conditionally stores only if no other write touched the reserved address. More composable than CAS for complex read-modify-write sequences.
**Hardware Implementation**
On x86, the LOCK prefix makes any read-modify-write instruction atomic by asserting a bus lock (legacy) or cache lock (modern — marking the cache line exclusive via the MOESI/MESIF coherence protocol). On ARM, exclusive monitor hardware tracks the reservation set by LDXR. On GPUs, atomic operations on global memory are handled by L2 cache controllers, with throughput varying dramatically by address contention.
**Lock-Free Data Structures**
- **Lock-Free Stack**: Push/pop using CAS on the head pointer. Michael's lock-free stack.
- **Lock-Free Queue**: Michael-Scott queue with CAS on head and tail pointers.
- **Lock-Free Hash Map**: CAS on each bucket's head pointer; per-bucket lock-free linked lists.
**Performance Considerations**
- **Contention**: When many threads atomically update the same address, cache line bouncing between cores causes 10-100x slowdown. Contention reduction techniques: per-thread counters with periodic merge, hierarchical combining trees, or backoff strategies.
- **ABA Problem**: CAS can succeed incorrectly if the address value changes from A→B→A between the load and the CAS. Solutions: tagged pointers (version counter in upper bits), hazard pointers, or epoch-based reclamation.
Atomic Operations are **the lowest-level synchronization primitive in parallel computing** — providing the hardware guarantee of indivisibility that enables all higher-level concurrent abstractions, from spinlocks and mutexes to lock-free data structures and transactional memory.