In 1967, an IBM engineer named Robert Tomasulo designed the floating-point unit of the
IBM System/360 Model 91 and, almost as a side effect, invented the algorithm that every high-performance
processor on Earth still uses today. It takes
The magic is that Tomasulo stopped thinking about instructions as waiting on registers, and made them wait on values-in-transit instead. Each pending result gets a unique tag; an instruction that needs it simply parks with that tag and springs to life the moment a value carrying that tag appears on a shared broadcast wire. Registers, it turns out, were never the real dependency — they were just names.
A machine has only a handful of architectural register names —
Instruction (l) wants to overwrite
Register renaming separates the architectural register a program names from the physical storage that actually holds the value. Every time an instruction writes a register, the hardware allocates it a brand-new physical location (in Tomasulo's design, the tag of a reservation station; in modern chips, a physical register from a large pool). Subsequent readers are pointed at the specific physical location that holds the value they want.
Below, a tiny renamer maps architectural names to a growing pool of physical names. Watch a reused name
like
Tomasulo's hardware has two new pieces. In front of each functional unit sit several reservation stations — little buffers that hold an instruction plus its operands (or, if an operand isn't ready, the tag it is waiting for). Threading through the whole machine is the common data bus (CDB): when any unit finishes, it broadcasts (tag, value) on the CDB, and every reservation station and register listening for that tag grabs the value in the same cycle. This is tag-based wakeup, and it is why results forward instantly.
Each instruction moves through three steps:
| Step | What happens |
|---|---|
| 1. Issue | Take the next instruction (in order). If a reservation station is free, allocate it. For each source operand: if its value is ready, copy it in; otherwise record the tag of the station that will produce it. Rename the destination by making the register point at this station's tag. (No free station ⇒ stall — a structural hazard.) |
| 2. Execute | When both operands have arrived (all tags resolved), and the functional unit is free, compute. Waiting on a tag is the RAW dependence — enforced naturally, with no separate hazard check. |
| 3. Write result | Broadcast (tag, value) on the CDB. Every waiting station and every register whose tag matches captures it simultaneously, and the station frees up. |
There is no separate "read operands" stall and no WAR/WAW checking anywhere — renaming has made those hazards impossible, so the hardware never has to look for them. The only stalls left are the honest ones: a true RAW dependence (wait for the tag) or a structural one (no free station or unit).
They fight — and the CDB is a genuine bottleneck. In Tomasulo's original design there is a
single common data bus, so if two functional units complete simultaneously, only one may broadcast; the
other waits a cycle. This is why modern superscalar processors have multiple result buses (and
multiple CDBs), and why the tag-match logic — every station comparing its stored tag against the broadcast
tag every cycle — is one of the most timing-critical, power-hungry circuits on the chip. The elegant idea
of "broadcast to everyone" gets expensive fast as you widen the machine, a theme that returns when we count
the quadratic cost of wide
A tempting overstatement: "renaming makes all dependences go away, so everything runs in parallel." No.
Renaming abolishes WAR and WAW, which were never real — they were name
collisions. A RAW dependence is a genuine flow of a value from producer to consumer, and
no amount of renaming can let the consumer run before the value exists. In Tomasulo the RAW dependence is
simply re-expressed as "wait for this tag on the CDB." If a chain of instructions each depends on the last
(
Tomasulo's 1967 design is the direct ancestor of the out-of-order engine in your phone and laptop. Modern
chips rename onto a pool of a few hundred physical registers (an Apple or AMD core has far more
physical than architectural registers precisely to expose more parallelism), forward results over several
buses, and add a