5.3.11 · D4Advanced Microarchitecture

Exercises — Speculative execution

3,532 words16 min readBack to topic

This page is a self-test ladder. Each rung asks harder questions about Speculative execution — from "can you name the part?" up to "can you design the mitigation?". Cover the solution, try it, then reveal.

Before we start, a one-screen refresher of the vocabulary we will keep reusing. If any word feels unfamiliar, that is exactly what these exercises will drill.

We measure everything in cycles (one tick of the CPU clock) and in CPI = cycles per instruction. Numbers we compute are checked in ===VERIFY===.


Building the penalty formula (read this first)

Every exercise below prices a wrong guess in cycles, so we must first understand where that price comes from. Picture the pipeline as a conveyor belt of stages; a branch instruction rides near the far end, but the instructions it "gates" were fetched right behind it and are already streaming down the belt.

We now have the two quantities every exercise uses: and , on a machine with .


Level 1 — Recognition

(Can you name and classify the pieces?)

Exercise 1.1

Sort each item into architectural or microarchitectural state: (a) general-purpose register rax, (b) the ROB, (c) the L1 data cache, (d) main memory, (e) the branch-predictor counter table.

Recall Solution

The test is: can a normal program read this directly?

  • Architectural (program can see): (a) rax, (d) main memory.
  • Microarchitectural (hidden helper): (b) ROB, (c) L1 cache, (e) predictor table.

Cache is the sneaky one: a program cannot read the cache directly, but it can time memory accesses and infer what is cached. That timing leak is the seed of every Spectre-style side-channel attack.

Exercise 1.2

Match each stage of speculation to its purpose:

  1. Predict — 2. Checkpoint — 3. Execute — 4. Verify — 5. Commit/Squash. Purposes: (A) run instructions from the guessed path; (B) guess the branch outcome; (C) make architectural state real or undo it; (D) save state so we can roll back; (E) compare the real branch result to the guess.
Recall Solution

1→B, 2→D, 3→A, 4→E, 5→C. The order matters: you checkpoint before you execute, because you cannot roll back to a state you never saved.


Level 2 — Application

(Plug numbers into the machinery.)

For Levels 2–3 use the baseline machine from the derivation above: pipeline depth , penalty cycles, stall cost cycles.

Exercise 2.1

A program runs branches. The predictor is accurate. How many cycles are wasted on mispredictions?

Recall Solution

Mispredicted branches: . Each costs cycles → cycles. Answer: cycles wasted.

Exercise 2.2

The loop from the parent note:

for (int i = 0; i < 100; i++) sum += array[i];

The i < 100 branch is taken times and not-taken once (the exit). Consider two different design strategies and their own stall costs:

  • (a) "in-order, drain-on-branch" — an old-style in-order core that cannot rename or reorder, so on every branch it must drain the whole pipeline before re-steering. Draining an -stage belt costs the full pipeline depth cycles per branch. (This is a stronger stall than our modern : this machine cannot even overlap the resolve with useful work.)
  • (b) speculation on the modern machine — pay the -cycle penalty only on the single misprediction (the loop exit).

Compute the total stall cycles for (a) and (b), then give the ratio (a)/(b).

Recall Solution

Why 15 here but elsewhere? The redirect assumes a modern out-of-order front end that only needs a quick re-steer. The (a) machine is deliberately a different, older design that drains all 15 stages on every branch — it has no cheap redirect, so its per-branch stall equals the whole depth . We compare the worst realistic non-speculative machine against speculation to show the full payoff. (a) stall cycles. (b) stall cycles. Ratio . Speculation removes ~ the stall cost here because the loop is almost perfectly predictable.

Exercise 2.3

A branch on random data (rand() % 2 == 0) is predicted correctly of the time. What is the average penalty per execution of this branch, and how does it compare to simply stalling the cycles (defined above) until the branch resolves?

Recall Solution

Expected penalty cycles per branch. A plain stall costs only cycles. Here speculation is cycles worse on average. For a 50/50 branch, not speculating wins.


Level 3 — Analysis

(Reason about trade-offs and rates.)

Exercise 3.1

A branch-heavy program executes one branch every instructions. Predictor accuracy is , penalty cycles. Compute the extra CPI (cycles per instruction) added by mispredictions.

Recall Solution

Fraction of instructions that are branches: . Of those, mispredict. Extra cycles per instruction: So roughly extra cycles per instruction — real, but far cheaper than stalling on every branch.

Exercise 3.2

Two predictor designs are offered for the same workload (branch every instructions):

  • Design A: accuracy , pipeline depth → penalty .
  • Design B: accuracy , pipeline depth → penalty . Which adds less misprediction overhead per instruction?
Recall Solution

Extra CPI .

  • A: CPI.
  • B: CPI. Design B wins (). The deeper pipeline (bigger penalty) is more than offset by the much lower miss rate. Deep pipelines only pay off when the predictor is good enough.

Exercise 3.3

The parent note links speculation to out-of-order execution via the ROB. Explain in 2–3 sentences why the ROB is what makes rollback possible, and what would break if speculative results were written straight to rax.

Recall Solution

The ROB holds speculative results in program order but not yet committed — a staging area. On a misprediction, the CPU simply discards the wrong ROB entries; architectural registers were never touched, so nothing to undo. If results were written straight to rax, a wrong guess would overwrite the real value with garbage and there would be no clean copy to restore — speculation would corrupt the program. The ROB is the checkpoint that separates computed from committed.


Level 4 — Synthesis

(Combine ideas into a security/design argument.)

Exercise 4.1 — The Spectre gadget

A malicious program wants to read a secret byte it is not allowed to read. It uses the sequence below. Label each step as architectural or microarchitectural, and explain why the secret still leaks even though step 3 is squashed.

  1. Train the branch predictor to expect "in-bounds".
  2. Pass an out-of-bounds index so the guard branch mispredicts into the forbidden path.
  3. Speculatively load secret, then load probe[secret * 256].
  4. Branch resolves → all of step 3 is squashed.
  5. Attacker times reads of probe[0], probe[256], ... to see which is fast.
Recall Solution
  • Steps 1, 3, 5 operate on microarchitectural state (predictor + cache). Step 4's squash restores architectural state.
  • The leak survives because squash only undoes architectural effects (registers, memory). It does not evict the cache line that step 3 pulled in. probe[secret*256] stays cached.
  • In step 5 the attacker reads all possible probe slots; the one fast (cached) slot reveals secret. See the timing sketch below.

Figure — Speculative execution
Figure s02 — a bar chart of eight probe slots (indices 0–7) with measured access time in cycles on the vertical axis. Seven bars stand tall near 120 cycles in lavender (evicted, slow); one bar at index 3 drops to about 42 cycles in mint (still cached, fast). A dashed coral "cache-hit threshold" line at 70 cycles separates them, and a coral arrow points at the short bar reading "fast = cached ⇒ secret is 3". The single fast slot's index is the leaked secret value.

This is the whole point of cache side channels: architectural rollback is not a security boundary because it forgets to undo the cache.

Exercise 4.2 — Which fix, and why

Match each mitigation to the exact step it disrupts: (A) lfence speculation barrier — (B) flushing predictor on context switch — (C) retpoline for indirect branches. Steps: (i) training the predictor across a privilege boundary; (ii) speculatively issuing the secret-dependent load; (iii) speculating through an indirect/call *reg branch.

Recall Solution
  • A → (ii): lfence stops execution proceeding speculatively past it, so the secret-dependent load never issues under speculation.
  • B → (i): clearing the predictor between contexts stops the attacker's training from carrying into the victim.
  • C → (iii): a retpoline replaces an indirect jump with a controlled ret-based trampoline the predictor cannot steer to an attacker target. Each fix attacks a different stage — which is why real CPUs deploy several together.

Level 5 — Mastery

(Design and defend a full decision.)

Exercise 5.1 — Speculate-or-stall decision rule

Derive the general condition under which speculation is worth it versus stalling. Reusing our two quantities: let = predictor accuracy, = misprediction penalty (cycles, here), = stall cost if we don't speculate (cycles, here). Then find the break-even accuracy , and say what happens exactly at that accuracy.

Recall Solution

Expected cost of speculating (you only pay the penalty when wrong; correct guesses cost ). Cost of stalling (always paid). Speculation wins when Break-even: . The tie case : here exactly — speculating and stalling cost the same on average, so neither is better and the choice is a wash (real designs then prefer stalling to avoid the security exposure of speculating). Strictly above , speculate; strictly below, stall.

Figure — Speculative execution
Figure s03 — a line plot with predictor accuracy (0 to 1) on the horizontal axis and expected cost in cycles per branch on the vertical axis. A flat coral line sits at the constant stall cost ; a sloped lavender line traces , falling from at to at . The two lines cross at the mint-dashed break-even , marked with a slate dot. The mint-shaded region to the right of the crossing is labelled "speculate wins"; the left region is labelled "stalling wins".

Exercise 5.2 — Redesign a bad branch

You profile a hot branch: accuracy , executed times, , and stalling would cost . (a) How many cycles does speculation waste vs. stalling? (b) Name two software rewrites (from the parent note) and say which one removes the branch entirely.

Recall Solution

(a) Speculating: cycles/branch → cycles. Stalling: cycles. Speculation wastes extra cycles. (Consistent with 5.1: , so speculation loses.) (b) Sort the data to make the branch biased/predictable, or write branchless code (cmov, bitwise select). The branchless rewrite removes the branch entirely, so there is nothing left to mispredict — the surest fix.

Exercise 5.3 — Tie it together

In one paragraph, connect Instruction-level parallelism (ILP), superscalar width, and speculation: why does a wider superscalar machine need better speculation?

Recall Solution

A superscalar core issues several instructions per cycle to exploit ILP — but branches occur every few instructions, so a wide machine hits a branch almost every cycle. Without accurate speculation it would stall constantly, and its extra issue slots would sit idle (the very hazard speculation exists to hide). Wider issue raises the cost of each stall (more idle slots) and raises the branch encounter rate, so the payoff of every 1% of predictor accuracy grows with width. Wide + deep machines and strong predictors are therefore inseparable.