NUMA-Aware Programming is the practice of structuring parallel applications to account for the non-uniform memory access costs of modern multi-socket systems — placing data in memory local to the processors that access it and scheduling threads to cores near their data, achieving 2-4× performance improvement over NUMA-oblivious approaches for memory-bandwidth-sensitive workloads.
NUMA Architecture:
- Multi-Socket Topology: each CPU socket has local DRAM channels providing ~200-400 GB/s bandwidth; accessing remote DRAM on another socket traverses inter-socket links (UPI, Infinity Fabric) with 1.5-3× higher latency and reduced bandwidth
- NUMA Nodes: each socket (or sub-socket on large processors) forms a NUMA node with its own memory controller; topology is exposed via /sys/devices/system/node on Linux and queried via hwloc or numactl
- Distance Matrix: NUMA distances quantify relative access costs; local access = distance 10 (reference); cross-socket = distance 20-32; cross-NUMA within one socket (sub-NUMA clustering) = distance 12-16
- Memory Interleaving: default Linux policy interleaves pages across NUMA nodes for average-case performance; dedicated applications benefit from explicit NUMA-local allocation
Memory Allocation Policies:
- First-Touch: Linux default for private allocations; page is allocated on the NUMA node where the first page fault occurs — initialization thread determines placement; parallel first-touch (each thread initializes its portion) distributes pages correctly
- numactl --membind/--interleave: command-line control of NUMA policy; --membind=N restricts allocation to node N; --interleave=0,1 distributes pages round-robin for shared data accessed by all sockets equally
- mbind/set_mempolicy: programmatic NUMA policy control at page granularity; MPOL_BIND forces allocation on specified nodes; MPOL_PREFERRED suggests a node but falls back if memory is unavailable; MPOL_INTERLEAVE distributes evenly
- Huge Pages: 2MB and 1GB huge pages reduce TLB misses and improve memory access predictability; NUMA-local huge page allocation requires explicit reservation (hugetlbfs) or transparent huge pages (THP) with NUMA awareness
Thread-Data Affinity:
- CPU Pinning: pthread_setaffinity_np or taskset binds threads to specific cores; ensuring thread i runs on the same NUMA node as its data partition eliminates cross-socket memory access
- OpenMP Affinity: OMP_PLACES=cores and OMP_PROC_BIND=close/spread control thread placement; close packing fills one socket before using the next (good for memory-intensive, socket-local workloads); spread distributing evenly across sockets maximizes aggregate bandwidth
- Work Partitioning: divide data arrays so that each NUMA node owns a contiguous chunk; assign threads on each node to process their local chunk; reduction operations across nodes use a two-level hierarchy (local reduce, then cross-node reduce)
- Migration Detection: Linux AutoNUMA (NUMA balancing) periodically unmaps pages and remaps them on the accessing node when consistent cross-node access is detected — automatic but introduces TLB shootdown overhead
Performance Diagnosis:
- perf stat -e numa-*: hardware performance counters track local vs remote memory accesses; remote access ratio >20% indicates NUMA placement issues for bandwidth-sensitive code
- numastat: reports per-node memory allocation statistics; large numa_miss counts indicate first-touch allocation on wrong nodes — initialization pattern needs correction
- Memory Bandwidth Measurement: STREAM benchmark per-node measures local bandwidth capacity; cross-node bandwidth is typically 30-50% of local — the NUMA penalty quantifies the optimization opportunity
- Intel VTune / AMD uProf: visualize NUMA access patterns and identify hot data structures causing cross-socket traffic; guide data layout reorganization and thread pinning decisions
NUMA-aware programming is essential for achieving peak performance on modern multi-socket servers — the 2-3× bandwidth difference between local and remote memory access means that memory placement and thread affinity decisions have a first-order impact on application throughput, especially for memory-bandwidth-bound HPC, database, and machine learning workloads.
Explore 500+ Semiconductor & AI Topics
From EUV lithography to CUDA optimization — search the full knowledge base or chat with our AI assistant.