Hardware Threads, Hyper-Threading, and SMT
Terminology
Hardware thread is the general, vendor-neutral term for a thread of execution the CPU tracks independently at the hardware level. Each one maintains its own architectural state and appears to the operating system as a separate logical processor it can schedule work onto.
Hyper-Threading (HTT) is Intel’s brand name for its implementation of simultaneous multithreading (SMT). A “hyperthread” is simply a hardware thread produced by Intel’s SMT. AMD implements the same concept but doesn’t brand it — they just call it SMT.
The hierarchy runs: physical core (the actual execution hardware) → hardware thread / logical processor (an independently schedulable execution context) → hyperthread (a hardware thread specifically created by Intel SMT). Every hyperthread is a hardware thread, but not every hardware thread is a hyperthread — a core without SMT still has exactly one hardware thread. A 4-core Intel CPU with HTT enabled reports 8 logical processors.
Is a thread physical or logical?
It sits in between, and this is the subtle part.
A hardware thread is not purely logical. Enabling SMT requires physically duplicating the structures that hold architectural state: the register file (or at least the register alias table), the program counter and instruction pointer, segment and control registers, APIC state, and similar. That’s real silicon — the commonly cited cost is roughly 5% additional die area per core.
What is not duplicated is the execution machinery: ALUs, FPU and vector units, load-store units, L1/L2 caches, branch predictor, and TLBs. These are shared between threads, sometimes statically partitioned (store buffer, reorder buffer split in half when both threads are active) and sometimes competitively shared (cache lines, which either thread can occupy).
So a physical core is the coherent, identifiable hardware unit, while a hardware thread is a context the core can hold and interleave. It exists physically as a set of state-holding registers plus a thread-ID tag attached to instructions flowing through the pipeline, that tag is how the core knows which context an in-flight instruction belongs to. There is no separate “thread engine.” Both threads’ instructions traverse the same pipeline in the same cycle, distinguished only by tags.
By contrast, a software thread (the OS-level concept) is entirely a logical abstraction. Therefore, OS doesn’t preempt hardware threads. It preempts software threads that are running on the hardware threads.
Kitchen analogy: the physical core is a kitchen with one set of stoves and counters. SMT adds a second recipe card holder and a second set of ingredient bins, so the cook can switch between two dishes whenever one needs to simmer. The second dish has real dedicated storage, but it doesn’t get its own kitchen.
What SMT actually buys you
SMT adds no compute capacity. It adds the ability to harvest compute capacity that would otherwise be wasted on stalls.
Execution is genuinely simultaneous, not just fast context switching. A modern core is superscalar with roughly 8–12 issue ports feeding different execution units, so in a single cycle thread A might issue to two integer ALUs while thread B issues a load and a branch. Sharing happens at the granularity of individual ports and units, not the whole core — which is why it’s called simultaneous multithreading.
But the pool of execution resources is fixed. If one thread already saturates it, the second thread gets nothing.
Where SMT fails: heavy AVX-512 or dense FMA code. A well-optimized matrix multiply kernel keeps both FMA units busy every cycle with no stalls, leaving the second thread nothing to slot into. Throughput gain approaches zero. This is why HPC and scientific computing shops often disable Hyper-Threading in BIOS.
Where SMT actively hurts: two threads sharing one L1 and L2 cache each get roughly half the cache and can evict each other’s data, so both run slower than either would alone. Structures like the store buffer and reorder buffer are statically partitioned when both threads are active, halving each thread’s out-of-order window. Databases and latency-sensitive workloads sometimes regress for these reasons.
Where SMT wins: code with frequent stalls that leave execution units idle — pointer-chasing through linked data structures, branchy code with mispredictions, workloads with many cache misses waiting on DRAM. During those hundreds of idle cycles, the other thread’s work fills the gap essentially for free. Web servers, compilers, and general mixed workloads typically see 15–30% throughput improvement.