What Is Simultaneous Multithreading (SMT)?
Simultaneous multithreading lets one physical CPU core run two instruction streams at once, filling idle execution units to raise throughput.
Simultaneous multithreading (SMT) is a CPU design technique that lets a single physical core execute instructions from two (or more) threads at the same time, sharing the core’s execution resources instead of dedicating them to one thread. The operating system sees each SMT-capable core as two logical cores, but there’s only one set of physical execution units underneath — SMT’s job is to keep those units busier than a single thread ever could on its own.
Why a core has room for a second thread
Modern CPU cores are superscalar and out-of-order: in a single cycle they can dispatch multiple instructions to several execution ports at once, and they reorder instructions to keep those ports fed while waiting on slow operations like memory loads. In practice, a single thread rarely uses every port every cycle. Branch mispredictions, cache misses, and data dependencies leave execution units idle far more often than you’d expect from a chip running “at full speed.”
SMT exploits that idle capacity. If one thread stalls waiting on a cache miss, the core can issue instructions from the second thread into the ports the first thread isn’t using that cycle. Neither thread runs faster in isolation — each still executes at whatever rate its own instructions allow — but the core’s overall throughput goes up because fewer cycles go completely to waste.
What’s shared, and what isn’t
Each logical thread on an SMT core typically gets its own architectural state — registers, program counter — so the operating system can schedule and context-switch it like an independent CPU. But the two threads share the actual hardware that does the work:
- Execution units and issue ports
- Caches (L1 and often L2, described in the cache hierarchy)
- Branch predictors and prefetchers
- Memory bandwidth to the rest of the system
That sharing is both the benefit and the limit. Two threads doing mostly independent, low-conflict work can genuinely both get faster in aggregate. Two threads that both hammer the same cache lines or the same execution ports will contend with each other and see smaller gains — sometimes even a slowdown for whichever thread gets scheduled second, since it now competes for cache capacity it would otherwise have to itself.
Physical cores vs logical cores
This is the source of a common point of confusion: an 8-core CPU with SMT reports 16 logical processors to the operating system, but it still only has 8 physical cores’ worth of execution hardware. Software that’s purely bound by execution throughput — heavy numeric code that keeps the pipeline full — often sees a modest gain from the extra logical cores, typically well short of doubling. Software that’s bound by memory latency or branch-heavy control flow, where cores spend a lot of time stalled, tends to benefit more, because that’s exactly the idle time SMT is designed to fill.
This matters for anything that reasons about parallelism directly, from SIMD-vectorized numeric code to systems tuned for NUMA memory locality — the logical-core count the OS reports isn’t the same resource as a genuinely independent physical core, and workloads that assume otherwise can end up contending for shared execution units instead of scaling.
Why the OS scheduler has to know about it
Because logical threads on the same physical core compete for shared resources, a scheduler that treats all logical processors as equally independent can make bad decisions. Placing two demanding threads on the two logical processors of the same physical core forces them to contend for one shared set of execution units; placing them on two logical processors that belong to different physical cores gives each its own full set of resources. A topology-aware scheduler generally prefers to spread independent, demanding threads across distinct physical cores first, and only doubles up on a core’s second logical thread once every physical core already has work — otherwise SMT’s throughput gain turns into unnecessary contention for workloads that didn’t need to share in the first place.
This is also why benchmarking or capacity planning that just counts “logical CPUs” can be misleading. A workload’s actual scalability depends on how much it can benefit from the second logical thread on each core, which varies enormously by workload — from close to nothing for cache- and bandwidth-bound code, to a meaningful throughput gain for latency-bound code with a lot of idle time to fill.
The security caveat
Because SMT threads share microarchitectural state — caches, predictors, execution ports — one thread can sometimes influence or observe timing effects caused by another thread running concurrently on the same core. This shared-resource contention is the same category of concern behind timing attacks more broadly: measurable timing differences can leak information across a boundary that’s supposed to be isolated. It’s why security-sensitive workloads sometimes disable SMT entirely, or pin untrusted and trusted threads so they never share a physical core.
SMT and virtualization
SMT also matters for anyone reasoning about virtual machine sizing, since a hypervisor typically presents logical processors — not physical cores — as the unit it schedules virtual CPUs onto. Two virtual machines that each believe they have a dedicated CPU thread may, in fact, be sharing a single physical core’s execution units and caches if the hypervisor placed them on the same core’s two logical threads. This is one reason cloud providers sometimes let customers choose between logical-core and physical-core pricing or scheduling options for latency-sensitive workloads — the difference between a full physical core and a shared logical thread can matter a great deal for predictable performance, even though both look identical from inside the guest operating system.
The takeaway
Simultaneous multithreading lets one physical core run two threads by sharing execution units, caches, and predictors between them, filling in the idle cycles a single thread leaves on the table. It raises aggregate throughput without adding physical execution hardware, but the gain depends heavily on how much the two threads contend for the same shared resources — and that same sharing is why SMT carries a security tradeoff, not just a performance one.
Keep reading
Chisato · · 4 min read What Is a Northbridge and Southbridge? The Chipset
The northbridge and southbridge were the two chips that routed data between a CPU, memory, and peripherals before modern SoCs absorbed their jobs.
Chisato · · 4 min read What Is Virtual Memory? Paging and Address Translation
Virtual memory gives every process its own private address space, mapped to physical RAM by the OS and CPU — enabling isolation, swapping, and overcommit.
Chisato · · 4 min read What Is a TLB? Translation Lookaside Buffer Explained
A TLB is a small CPU cache that stores recent virtual-to-physical address translations, avoiding a slow page-table walk on every memory access.