The Case for Multicore
For thirty years, computer architects had a beautiful deal with physics. Every couple of years transistors
shrank, clocks got faster, and a single processor core simply ran your old program faster — no
rewrite, no effort. Then, around 2004–2005, the deal collapsed. Intel cancelled its
4\ \text{GHz} Pentium 4, and the whole industry pivoted, almost overnight, from
making one fast core to packing many simpler cores onto a chip. Your laptop today has 8,
12, maybe 16 of them.
This lesson is about why that pivot was forced — not chosen. Two walls closed in at once: the
ILP wall (we ran out of ways to make one instruction stream go faster) and the
power wall (we ran out of watts to spend on clock speed). Multicore is the industry's
answer, and it hands the hard part — finding parallel work — straight to the programmer.
The power wall: watts, not gates, are the limit
The dynamic power a CMOS chip burns switching its transistors is
P_{\text{dyn}} \;=\; \alpha\, C\, V^2 f,
where \alpha is the activity factor, C the switched
capacitance, V the supply voltage and f the clock
frequency. The killer is that to clock faster you must also raise the voltage, because the
transistors need a bigger gate drive to switch in less time. Power depends on V^2 f,
so pushing frequency drags voltage up with it and power climbs super-linearly — roughly
with the cube of frequency. A modest 40\% clock bump can nearly double the power.
Meanwhile Dennard scaling — the rule that let voltage fall as transistors shrank, keeping
power density constant — broke down in the mid-2000s. Leakage current stopped voltage from dropping any
further. Suddenly a smaller, faster core did not stay cool. Chips slammed into a hard ceiling of
about 100\text{–}150\ \text{W}, the most you can dissipate through a cheap heat
sink and a fan. Frequency has been stuck around 3\text{–}5\ \text{GHz} ever since.
- dynamic power is P_{\text{dyn}} = \alpha C V^2 f, and since a higher
f demands a higher V, power grows roughly as
f^3;
- with Dennard scaling dead, shrinking transistors no longer lowers power density, so
there are no free frequency gains left;
- a chip's power budget (its cooling limit) is fixed, so architects must buy performance
within a watt ceiling, not above it.
Why many slow cores beat one fast core
Here is the whole argument in one picture. Suppose you want k\times more
performance. Get it from one core by cranking the clock, and the power cost rises like
k^{\alpha} with \alpha \approx 3 — brutal. Get the
same k\times by using k cores at the base clock, and
the power cost rises only linearly, like k. Drag the exponent slider:
the single-core curve rockets away while the multicore line stays gentle. That gap is the entire case for
multicore.
Equivalently: at a fixed power budget, two cores at 0.8\times the clock deliver
far more total work than one core at 1.0\times, because that last sliver of
frequency is the most expensive watt you will ever spend.
The ILP wall: the other reason
Power was not the only wall. Through the 1990s architects spent their transistor budget making a single
core extract instruction-level
parallelism — issuing several instructions per cycle, executing them out of order, predicting
branches. But the returns collapsed: doubling the issue width or the reorder buffer bought only a few
percent more real-world performance, because typical code simply does not contain enough independent
instructions to keep an ever-wider machine busy. You were spending exponentially more transistors and watts
to squeeze a single thread that had run dry of parallelism.
So the transistors that Moore's law kept delivering had to go somewhere useful. If one thread cannot use
them, give them a second thread — a whole second core. Multicore reframes the question from "how
do I make this one program faster?" (which physics forbade) to "how do I run many things at once?" (which
the operating system and the programmer can arrange).
Amdahl's shadow: the catch
Multicore is not a free lunch. Concurrency
must be found in the software, and Amdahl's law hangs over every core you add: if a
fraction (1-p) of the work is stubbornly serial, then no number of cores can beat
a speedup of 1/(1-p). Sixty-four cores on a program that is
90\% parallel still tops out near 10\times. Run the
code and watch the cores stop paying off:
// Amdahl on a multicore chip: speedup from N cores when fraction p is parallel.
function speedup(p: number, cores: number): number {
return 1 / ((1 - p) + p / cores);
}
const p = 0.90; // 90% of the work parallelises across cores
console.log(`parallel fraction p = ${p}, hard ceiling = ${(1 / (1 - p)).toFixed(1)}x`);
for (const cores of [1, 2, 4, 8, 16, 32, 64, 128]) {
const s = speedup(p, cores);
const perCore = (s / cores * 100).toFixed(0);
console.log(`${cores} cores\tspeedup ${s.toFixed(2)}x\tefficiency ${perCore}%`);
}
console.log("Note how efficiency (speedup per core) collapses — Amdahl's shadow.");
Homogeneous vs heterogeneous cores
Once you have decided on many cores, a second choice appears: should they all be the same? A
homogeneous chip has identical cores — simple to schedule, and what most desktop x86 chips
did for years. A heterogeneous chip mixes core types. ARM's big.LITTLE (and
Intel's later performance-core / efficiency-core designs, and Apple's M-series) pairs a few big, fast,
power-hungry cores with several small, slow, thrifty ones.
The insight is again Amdahl's: the serial part of a program wants one big fast core, while the
parallel part wants many efficient ones. A heterogeneous chip serves both — it runs your
single-threaded burst on a big core, then parks background work on the little cores sipping milliwatts.
Your phone does exactly this thousands of times a second to stretch its battery.
| Design | Cores | Best for | Example |
| Homogeneous | all identical | predictable, uniform parallel workloads | classic Xeon / Ryzen |
| Heterogeneous (big.LITTLE) | big + little mix | bursty phone/laptop work, battery life | Apple M-series, Intel P+E, ARM |
The Pentium 4's "NetBurst" microarchitecture was built to scale to blistering clock speeds — its pipeline
was stretched to 31 stages precisely so each stage could be short and the clock
high. Intel publicly promised 4\ \text{GHz}, even 10\ \text{GHz}
someday. Then the chips started melting: the 3.8\ \text{GHz} parts already ran
hot enough to worry about, and the 4\ \text{GHz} version was
cancelled in 2004. Intel abruptly abandoned NetBurst, went back to the cooler Pentium M
design from its laptop team, and shipped the dual-core "Core" chips that defined the next era. The power wall
killed the gigahertz race in public, on a roadmap.
The single most common beginner mistake is to assume a 16-core chip makes any program
16\times faster. It does nothing of the sort. A purely sequential program uses
exactly one core and leaves the other fifteen idle — it may even run slower than
on an older chip with a higher single-core clock. Cores only help work that has been deliberately split into
parallel threads, and even then Amdahl's serial fraction caps the payoff. Multicore moved the burden of
performance from the hardware designer onto the programmer: the free lunch is over.