4.1.23Computer Architecture (Deep)

Superscalar — multiple execution units

2,099 words10 min readdifficulty · medium

WHAT is it?


WHY does it exist? (first-principles)

A single-issue 5-stage pipeline can finish at most one instruction per cycle. But real code contains instructions that do not depend on each other. Example:

a = b + c     // uses b, c
d = e + f     // uses e, f  — independent of line 1!

If two adders sit idle, we are wasting silicon. The whole motivation is: transistors are cheap, time is precious — replicate functional units and run independent work simultaneously.


HOW: deriving the performance model from scratch

Start from the universal CPU performance equation. We derive it, not quote it.

Time to run a program = (number of instructions) × (time per instruction).

T=Ninst×CPI×TcycleT = N_{\text{inst}} \times \text{CPI} \times T_{\text{cycle}}

where NinstN_{\text{inst}} = dynamic instruction count, CPI\text{CPI} = average Cycles Per Instruction, TcycleT_{\text{cycle}} = clock period. Now invert CPI:

IPC=1CPIT=NinstTcycleIPC\text{IPC} = \frac{1}{\text{CPI}} \quad\Longrightarrow\quad T = \frac{N_{\text{inst}}\, T_{\text{cycle}}}{\text{IPC}}

Why this matters: a superscalar machine attacks the IPC term. A scalar pipeline caps IPC at 1; an N-wide superscalar raises the ceiling to N. So:

Why we rarely hit IPC = N (Amdahl-flavoured reasoning)

Suppose fraction pp of instructions can be parallelized perfectly across N units, and fraction (1p)(1-p) must run serially (chained dependencies). Then effective IPC is bounded:

IPCeff=1(1p)+pN\text{IPC}_{\text{eff}} = \frac{1}{(1-p) + \dfrac{p}{N}}


Figure — Superscalar — multiple execution units

The three obstacles (and how superscalars fight them)

Weapons:

  • Register renaming removes false dependencies (WAR, WAW) by mapping the same architectural register name to different physical registers.
  • Out-of-order execution + Reorder Buffer (ROB) lets ready instructions overtake stalled ones, then retires them in order for correctness.
  • Branch prediction + speculation keeps the units fed past branches.
  • Multiple ports on register file / caches dissolve structural hazards.

Worked Example 1 — counting cycles, in-order, 2-wide

Code (each op takes 1 cycle, latency 1):

I1: r1 = r2 + r3
I2: r4 = r5 + r6     (independent of I1)
I3: r7 = r1 + r4     (needs r1 from I1, r4 from I2)
I4: r8 = r9 + r10    (independent)

2-wide, in-order, two integer ALUs.

Cycle Issued together Why this step?
1 I1, I2 Both independent → fill both ALUs.
2 I3 stalls? No — r1,r4 ready end of C1 → I3, I4 I3's operands produced in C1, available C2; I4 independent → both issue.

Total = 2 cycles for 4 instructions → IPC = 2 (peak!). A scalar machine would take 4 cycles (IPC = 1). Speedup = 2×.

Worked Example 2 — a dependency chain destroys ILP

I1: r1 = r2 + r3
I2: r4 = r1 + r5     (needs r1)
I3: r6 = r4 + r7     (needs r4)
I4: r8 = r6 + r9     (needs r6)

Every instruction depends on the previous one.

Cycle Issued Why this step?
1 I1 I2 cannot issue, needs r1 not yet ready. Second ALU idle.
2 I2 r1 now ready; I3 still waiting on r4.
3 I3 chain continues.
4 I4 chain continues.

4 cycles, IPC = 1 — no benefit from the second unit. This is p=0p=0 in our formula. Steel-man lesson: width helps only if independent work exists.

Worked Example 3 — false dependency fixed by renaming

I1: r1 = r2 + r3
I2: r1 = r4 + r5     (WAW: writes r1 again — but value independent!)

In-order naive view says "both write r1, serialize." But the values are independent. Rename: I2 writes physical p7 instead of reusing r1's physical reg. Now they issue together, IPC = 2.

Why this step? Renaming proves the conflict was a naming artifact, not a real data flow.



Recall Feynman: explain to a 12-year-old

Imagine a kitchen with one cook making sandwiches one at a time — that's a normal CPU. A superscalar CPU is a kitchen with several cooks working at once. If the orders are independent ("a ham sandwich" and "a cheese sandwich"), all cooks work together and food comes out super fast. But if an order says "first toast the bread, then add butter, then add jam" — each step needs the last one — extra cooks just stand around waiting. So more cooks help only when there's independent work to share.


Flashcards

What does "superscalar" mean?
A pipelined CPU with multiple execution units that can issue/complete more than one instruction per clock cycle (IPC can exceed 1).
What is issue width N?
The maximum number of instructions that can be dispatched to execution units per cycle; it is the ceiling on IPC.
Relationship between IPC and CPI?
IPC = 1/CPI; they are reciprocals.
CPU performance equation?
T = N_inst × CPI × T_cycle = N_inst × T_cycle / IPC.
Effective-IPC formula for parallel fraction p over N units?
IPC_eff = 1 / ((1-p) + p/N).
Why is real IPC much less than N?
Data hazards (dependency chains), structural hazards, and control hazards (branches) prevent full parallel issue.
Difference between superscalar and superpipelining?
Superscalar widens (more units → lower CPI); superpipelining deepens (more stages → higher clock). Orthogonal, often combined.
What does register renaming fix?
False dependencies (WAR and WAW) caused by reusing register names, by mapping to distinct physical registers.
Why does out-of-order execution stay correct?
Instructions execute out of order but commit/retire in program order via the Reorder Buffer.
The three hazard types?
Data, Structural, Control.
If p=0 (pure dependency chain) what is IPC on an N-wide core?
1 — width gives no benefit when every instruction depends on the previous.

Connections

Concept Map

uses

runs independent work

exploits

defined by

caps

inverse of

lowers

IPC less than N due to

raises real

requires

can be

Superscalar CPU

Multiple execution units

Instruction-Level Parallelism

Issue width N

IPC

CPI

Program time T

Out-of-order issue

Register renaming plus ROB

Dependencies and hazards

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, normal pipelined CPU ek hi lane wali checkout jaisi hai — best case mein har clock cycle mein sirf ek instruction complete hota hai, yani IPC = 1. Superscalar processor mein hum extra execution units (do ALU, ek multiplier, ek load/store unit, FPU) laga dete hain. Ab agar do instructions ek dusre par depend nahi karte, to dono ek saath issue ho jaate hain. Isse throughput badhta hai — instruction fast nahi hua, balki ek samay mein zyada instructions chal rahe hain.

Speed kahan se aati hai? Performance equation se: T=Ninst×CPI×TcycleT = N_{inst} \times CPI \times T_{cycle}, aur IPC=1/CPIIPC = 1/CPI. Scalar CPU ka IPC max 1 hota hai; N-wide superscalar ka ceiling N ho jaata hai. Lekin yaad rakho — real code mein dependencies hoti hain. Agar har instruction pichle ke result ka wait kare (dependency chain), to extra units bekaar khade rahenge aur IPC wapas 1 ho jaayega. Iska formula: IPCeff=1/((1p)+p/N)IPC_{eff} = 1/((1-p) + p/N), jahan pp = parallel fraction.

Teen dushman hain: Data hazard (result ready nahi), Structural hazard (ek hi unit do log maang rahe), aur Control hazard (branch — pata nahi aage kaunsa instruction). Inse ladne ke liye CPU register renaming (false dependency hatao), out-of-order execution + reorder buffer (ready instruction aage nikal jaaye par commit order mein ho), aur branch prediction use karta hai.

Do common galtiyan: (1) Superscalar aur superpipelining same nahi hain — width vs depth. (2) "N-wide matlab N guna fast" galat hai; real IPC usually 1.5–2.5 hota hai 4-wide core par. Bas yaad rakho: independent kaam ho to hi extra cooks kaam aate hain.

Go deeper — visual, from zero

Test yourself — Computer Architecture (Deep)

Connections