numa aware programming

**NUMA-Aware Programming** is the **performance optimization discipline for multi-socket and chiplet-based systems where memory access latency and bandwidth depend on the physical location of the memory relative to the processor — where NUMA-oblivious code can suffer 2-4x performance degradation because remote memory accesses (cross-socket or cross-chiplet) take 1.5-3x longer than local accesses, making data placement and thread affinity the dominant factors in memory-bound application performance**. **NUMA Architecture** In a NUMA system, each processor (socket/chiplet) has its own local memory controller and DRAM. Accessing local memory: ~80-100 ns. Accessing remote memory (through the interconnect — Intel UPI, AMD Infinity Fabric): ~130-200 ns. The latency asymmetry is the "non-uniform" in NUMA. **Example: 2-Socket AMD EPYC** Each socket has 4 CCDs (chiplet core dies), each with its own L3 cache and a local slice of the memory channels. Memory access hierarchy: 1. Same CCD L3: ~10 ns 2. Same socket, different CCD: ~30-50 ns 3. Same socket, different memory controller: ~80-100 ns 4. Remote socket: ~130-200 ns **NUMA Optimization Techniques** - **First-Touch Allocation**: Linux NUMA default policy. Memory pages are allocated on the NUMA node of the first thread that touches (writes to) them. If the initializing thread is on node 0 but the computing thread is on node 1, all accesses are remote. Fix: initialize data on the same threads that will process it. - **Thread-Memory Affinity**: Bind threads to specific cores/NUMA nodes using `numactl --cpunodebind=0 --membind=0`, `sched_setaffinity()`, or OpenMP `OMP_PLACES=cores OMP_PROC_BIND=close`. Ensures threads access local memory. - **Interleaved Allocation**: `numactl --interleave=all` distributes pages round-robin across all nodes. Provides uniform average latency at the cost of no locality optimization. Useful for shared data accessed by all nodes equally. - **NUMA-Aware Data Structures**: Allocate per-node copies of frequently-read data (replication). For producer-consumer patterns, place the buffer on the consumer's node (reads are more latency-sensitive than writes due to store buffers). **Detecting NUMA Issues** - `numastat -p `: Shows per-node memory allocation and remote access counts. - `perf stat -e node-load-misses,node-store-misses`: Hardware counters for remote memory accesses. - Intel VTune / AMD uProf: NUMA-specific analysis modes visualize memory access locality. **NUMA in Practice** - **Databases**: PostgreSQL, MySQL allocate buffer pools NUMA-aware. Connection threads are pinned to the same node as their buffer pages. - **HPC**: MPI rank placement matches NUMA topology. One rank per NUMA node, with OpenMP threads within each rank placed on the same node. - **Cloud/VMs**: VM placement must respect NUMA boundaries. A VM spanning two NUMA nodes suffers remote access penalties on half its memory. **NUMA-Aware Programming is the essential optimization for modern multi-socket and chiplet servers** — ensuring that data lives close to the processor that uses it, because in a NUMA system, WHERE you allocate memory matters as much as HOW you access it.

Go deeper with CFSGPT

Get AI-powered deep-dives, save terms, and run advanced simulations — free account.

Create Free Account