CPU Affinity
Restricting which cores a thread may run on, which matters most on processors whose cores are not all alike.
CPU affinity is the set of cores a thread or Process is allowed to run on. By default it is all of them, and the CPU Scheduler moves threads freely between cores to balance load. Setting affinity (taskset, sched_setaffinity, or a cgroup's cpuset) restricts that freedom, either to keep a thread somewhere specific or to keep other work away from it.
Pinning helps in a few situations:
- Cache locality. A thread that migrates leaves its warm caches behind. Keeping it on one core, or on cores sharing a cache, avoids paying to refill them.
- Isolation. Reserving cores for latency-sensitive work (an audio thread, a game, a packet-processing loop) and moving everything else off them reduces interference more reliably than priority alone. Hypervisors pin virtual CPUs to physical cores for the same reason.
- Memory locality. On multi-socket (NUMA) machines, a thread is faster on the socket closest to its memory.
Affinity matters most on heterogeneous processors, where cores are not interchangeable. ARM's big.LITTLE designs, and Intel's hybrid chips since Alder Lake, pair fast performance cores (P-cores) with smaller, slower efficiency cores (E-cores). On the Intel parts, P-cores also run two hardware threads each and E-cores run one, so logical CPU numbers don't map evenly onto physical cores. A thread that lands on an E-core at the wrong moment runs at a fraction of the speed, and for a game that shows up as an uneven Frame Pacing spike rather than a lower average. The hardware provides hints to the scheduler about which threads belong where, but that support varies by operating system and kernel version. A common manual arrangement is to pin the foreground application to P-cores and confine background services and system daemons to E-cores.
The costs are real. A pinned thread can't escape a busy core, so badly chosen affinity produces Resource Starvation on one core while others sit idle. Affinity is inherited by child processes, so a restriction applied to a launcher quietly applies to everything it starts. And because a manual pinning scheme encodes one machine's topology, it is configuration that does not port, and it has to be undone when the work is done.
See also3
Concurrency and Parallelism
Concurrency is structuring independent tasks together; parallelism is actually running them at the same instant.
Computation & Algorithms8 connections
Hybrid CPU Architecture
Processors that mix large fast cores with small efficient ones on one chip, first in phones and now in laptops and desktops, which saves power and adds throughput but hands the operating system a hard scheduling problem.
Systems & Tooling5 connections
Thread Pool
A fixed set of threads kept alive to run many short tasks from a queue, avoiding the cost of creating a thread per task and capping concurrency, with sizing rules and failure modes that shape how servers and runtimes behave under load.
Systems & Tooling10 connections
Linked from6
- Control GroupsSystems & Tooling
The Linux kernel feature that caps and accounts for a process group's CPU, memory, and I/O — the resource-limiting half of a container.
- CPU SchedulerSystems & Tooling
The part of the kernel that decides which runnable thread gets each CPU core next, and for how long, trading throughput against latency.
- Dynamic Voltage and Frequency ScalingSystems & Tooling
Adjusting a processor's voltage and clock speed on the fly to match the work, exploiting the fact that power rises with the square of voltage.
- Frame PacingGraphics & Rendering
How evenly frames are delivered over time, which shapes perceived smoothness more than average frame rate does.
- Hybrid CPU ArchitectureSystems & Tooling
Processors that mix large fast cores with small efficient ones on one chip, first in phones and now in laptops and desktops, which saves power and adds throughput but hands the operating system a hard scheduling problem.
- Thread PoolSystems & Tooling
A fixed set of threads kept alive to run many short tasks from a queue, avoiding the cost of creating a thread per task and capping concurrency, with sizing rules and failure modes that shape how servers and runtimes behave under load.