JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

Latency, Throughput, and the Iron Law

We have built a fast machine — but what does 'fast' even mean? This guide pins the word down: latency versus throughput, the one equation that governs CPU time, why megahertz and MIPS lie to you, and how Amdahl's law caps the speedup you can ever buy.

What does 'fast' even mean?

Through the last rungs we built a real machine — a pipeline retiring close to an instruction per cycle, a cache feeding it, out-of-order execution working around stalls. Engineers kept calling each trick a way to make the machine 'faster'. But 'fast' is a slippery word, and before we can measure or improve performance we have to say exactly which fast we mean. There are two, and they are not the same thing.

The first is latency, also called response time: how long one task takes from start to finish. The second is throughput, also called bandwidth: how many tasks finish per unit time. A surgeon who takes four hours per operation has high latency per patient; a clinic with fifty surgeons working at once has high throughput regardless of how slow any one operation is. The two can move independently — and the whole reason pipelining exists is that it raises throughput while leaving the latency of a single instruction untouched, even slightly worse.

The iron law: one equation that governs run time

If you keep only one equation from this entire rung, keep this one. The time a program takes on a CPU is exactly the product of three things — the iron law of performance: CPU time = instruction count x CPI x cycle time. Instruction count is how many instructions the program runs; CPI is the average cycles per instruction; and cycle time is the seconds per clock cycle, the reciprocal of the clock rate. Multiply seconds-per-cycle by cycles-per-instruction by instructions, and the cycles and instructions cancel to leave seconds. It is just unit bookkeeping, but it is ruthless.

What makes the iron law so useful is that each factor belongs to a different layer of the stack, and each layer can only push on its own factor. The algorithm and compiler set the instruction count. The microarchitecture — pipeline, caches, branch prediction — sets the CPI. The circuit and process technology set the cycle time. So when someone says they sped up a program, the honest question is always: which of the three factors did you move, and did you accidentally make another one worse? Cutting instruction count with a fancier instruction often raises CPI; raising the clock rate often forces a higher CPI through more stalls.

  CPU time  =  instruction count  x  CPI  x  cycle time
              (   how many   )    (cycles  )  (seconds )
              ( instructions )    (  per   )  (  per   )
              (    we run    )    (  instr )  ( cycle  )

  who controls each factor:
    instruction count  <-  algorithm + compiler + ISA
    CPI                <-  microarchitecture (pipeline, cache, branch pred.)
    cycle time         <-  circuits + process technology (the clock)

  example: 1e9 instrs  x  1.5 CPI  x  0.25 ns/cycle  =  0.375 s
The iron law and who owns each factor. A speedup is real only if you lower one factor without quietly inflating another.

Why megahertz and MIPS lie

Now we can dismantle the oldest marketing trick in computing: the megahertz myth, the belief that a higher clock rate means a faster machine. The iron law shows why that is false. Clock rate only sets the cycle-time factor; it says nothing about the other two. A 4 GHz chip that needs three cycles per instruction and runs bloated code can easily lose to a 3 GHz chip that averages one cycle per instruction on tighter code. Raising the clock while letting CPI or instruction count balloon buys you nothing — and pushing the clock usually forces CPI up, because the memory does not get any closer when the clock speeds up.

Its cousin is MIPS, millions of instructions per second. It sounds like a speed, but it counts instructions, not work done. Recall that RISC vs CISC designs do the same job with wildly different instruction counts — a MIPS rating rewards a machine for running more, smaller instructions even if the program is no faster, and it cannot be compared across different instruction sets at all. Floating-point FLOPS has the same disease: it counts arithmetic operations, which is meaningful only for number-crunching code and ignores everything else. Both numbers measure activity, not accomplishment.

Speedup and Amdahl's law: the ceiling on improvement

When we improve a machine, we want to name how much by. Speedup is just the ratio of old time to new time: if a program drops from 10 seconds to 4, the speedup is 10/4 = 2.5x. The trap is that we usually improve only part of a program — we make a hot loop run on more cores, or accelerate the floating-point but not the rest. And here a beautiful, deflating piece of arithmetic takes over: Amdahl's law.

Amdahl's law says: if a fraction f of the work is sped up by a factor s, while the remaining (1 - f) is untouched, the overall speedup is 1 / ((1 - f) + f/s). Walk through what that means at the extreme. Suppose 90% of the program is perfectly parallel (f = 0.9) and you throw infinite cores at it (s goes to infinity, so f/s vanishes). The best speedup you can ever reach is 1 / (1 - 0.9) = 1 / 0.1 = 10x — no more, ever, because the 10% serial part still has to run. The part you did not speed up becomes the ceiling, and that ceiling is brutally low.

This is exactly why more cores rarely buys proportional speedup, and why a GPU full of a thousand tiny workers is wasted on serial, branchy code. It is also the deep justification for an old architect's slogan — make the common case fast: there is no point pouring effort into a rare case, because Amdahl's law caps how much that effort can ever return. Improvement is governed not by how fast you make the fast part, but by how much of the program you left slow.

Benchmarking right, and the honest synthesis

Since no single headline number is trustworthy, real measurement means running a suite of representative programs and timing them — a benchmark. The industry-standard ones, like the SPEC suites, are a basket of real applications precisely so no one workload can dominate. But how do you boil many programs' speedups into one number honestly? Not with a plain average: if program A speeds up 10x and program B slows to 0.1x, their ordinary mean is a misleading 5.05x even though, taken together, nothing got faster overall.

The fix is the geometric mean — multiply the n ratios and take the n-th root. For our 10x and 0.1x, the geometric mean is the square root of (10 x 0.1) = the square root of 1 = 1x, honestly reporting 'no net change'. It has the crucial property that the ranking it produces does not depend on which machine you chose as the baseline. That said, benchmarks are endlessly gamed: vendors tune compilers to detect benchmark code, or pick suites that flatter their chip. A benchmark only tells you the truth about your own work if it resembles your own work.

So we end where honesty demands: there is no single 'speed' of a computer. Latency matters to the person waiting for one reply; throughput matters to the datacenter serving millions; FLOPS matters to the physicist; energy will matter most of all in the next guides. The iron law tells you what you can move and which layer owns it; Amdahl's law tells you how much moving one part can ever return; benchmarks and the geometric mean tell you whether you actually moved it. The right metric is never universal — it is whichever one measures the thing you actually care about.