Table of Contents
numactl Basics
NUMA (Non-Uniform Memory Access) is the hardware reality of multi-socket systems. Each CPU socket has its own memory controller and DIMMs; a thread on socket 0 accessing memory on socket 1 crosses the inter-socket interconnect and pays extra latency. Modern CPUs mitigate this with caches, but bandwidth-heavy HPC code suffers measurably.
Install numactl:
sudo apt install numactl # Debian/Ubuntu sudo dnf install numactl # Fedora/RHEL
Discover the topology:
numactl --hardware
This shows available nodes (sockets), which CPUs belong to each node, memory per node, and the distance matrix (relative latency between nodes).
Example output:
available: 2 nodes (0-1) node 0 cpus: 0 1 2 3 4 5 6 7 node 0 size: 64000 MB node 1 cpus: 8 9 10 11 12 13 14 15 node 1 size: 64000 MB node distances: node 0 1 0: 10 21 1: 21 10
Distance values are relative latency costs. Local access (node 0 from cores on node 0) costs 10 units. Cross-socket (node 1 from cores on node 0) costs 21 units—roughly 2x slower. Actual latency depends on hardware; these are relative numbers.
Understanding the numbers:
- available: 2 nodes (0-1) — 2 NUMA nodes (sockets), numbered 0 and 1
- node 0 cpus: 0 1 2 3 4 5 6 7 — cores 0-7 are on socket 0
- node 0 size: 64000 MB — socket 0 has 64GB of memory
- Distance matrix — [i,j] entry is relative latency from node i to node j
On a 4-socket or 8-socket machine, the distances are more complex, but the principle is the same: local access is fastest, and cross-socket costs increase with distance.
Other tools:
lscpu # show CPU topology (simpler than NUMA view) numastat # show memory distribution numastat -p PID # show memory placement for a process taskset # simpler CPU pinning (no memory control)
numactl is the comprehensive tool for NUMA control; taskset is simpler if you only care about CPU affinity. For HPC, use numactl to control both CPU and memory placement together.
