5.3.7 · D4Advanced Microarchitecture

Exercises — Branch prediction (static and dynamic)

2,676 words12 min readBack to topic

Before we begin, one number we will reuse everywhere — the average cycles-per-instruction cost of mispredictions:


Level 1 — Recognition

Exercise 1.1

Match each scheme to its defining property.

  1. Predict Not-Taken (PNT)
  2. Predict Taken (PT)
  3. BTFNT
  4. 1-bit BHT
  5. 2-bit saturating counter

Options: (a) always fetches PC+4, (b) always fetches the target, (c) uses branch-target-vs-PC direction, (d) stores the last outcome per branch, (e) needs two mispredictions in a row to flip its guess.

Recall Solution

1 → (a): PNT always takes the fall-through, the next sequential instruction PC+4. 2 → (b): PT always takes the target address. 3 → (c): BTFNT predicts taken when the target is behind the branch (backward = a loop), not-taken otherwise. 4 → (d): the 1-bit Branch History Table simply remembers the last outcome of that branch. 5 → (e): the 2-bit counter has hysteresis — one wrong guess only nudges it, it takes two to change the prediction.

Exercise 1.2

A branch's target address is 0x0040 and the branch instruction lives at 0x00A0. Under BTFNT, does the CPU predict taken or not-taken?

Recall Solution

Target 0x0040 is less than the branch address 0x00A0, so the jump is backward. BTFNT rule: backward ⇒ Predict Taken. This is the loop case — the branch jumps back to the top of a loop.


Level 2 — Application

Exercise 2.1

A program is 20% branches. Branches mispredict 8% of the time. The flush penalty is 12 cycles. Compute the average CPI.

Recall Solution

Plug straight into the master formula: Multiply left to right: , then . Interpretation: mispredictions add 19.2% overhead on top of the ideal 1 CPI.

Exercise 2.2

Same machine, but you swap in a better predictor that cuts the mispredict rate from 8% to 3%. What is the new CPI, and by what percentage did total execution time drop?

Recall Solution

New CPI: Execution time is proportional to CPI (same instruction count, same clock). Speed-up ratio: Time saved = , about a 10.1% reduction in runtime.

Exercise 2.3

Trace a 1-bit predictor on a loop that runs the pattern T, T, T, T, NT once (4 taken, then exit). The BHT entry starts at 0 (Not-Taken). Fill in prediction, correct?, and next state for all 5 events. What is the accuracy?

Recall Solution

Rule reminder: predict what the bit says; then set the bit to the actual outcome.

Event Actual State before Predict Correct? State after
1 T 0 (NT) NT 1 (T)
2 T 1 (T) T 1 (T)
3 T 1 (T) T 1 (T)
4 T 1 (T) T 1 (T)
5 NT 1 (T) T 0 (NT)

Correct = 3 out of 5 ⇒ accuracy = 60%. Wrong on the first (cold start) and last (exit) events — the two boundaries.


Level 3 — Analysis

Exercise 3.1

Trace a 2-bit saturating counter on the pattern T, T, T, T, NT (same loop as 2.3), starting at 00 (Strongly Not-Taken). Compare its accuracy against the 1-bit result from 2.3. Then argue what happens if the loop is entered a second time.

Recall Solution

Encoding: 00=SNT, 01=WNT, 10=WT, 11=ST. Predict Taken iff counter 10. Increment on T (cap 11), decrement on NT (floor 00).

Event Actual Counter before Predict Correct? Counter after
1 T 00 (SNT) NT 01 (WNT)
2 T 01 (WNT) NT 10 (WT)
3 T 10 (WT) T 11 (ST)
4 T 11 (ST) T 11 (ST)
5 NT 11 (ST) T 10 (WT)

Correct = 2 of 5 ⇒ 40% on this cold pass — worse than the 1-bit's 60% here! The reason: the 2-bit counter needs two taken events just to start predicting taken, so it wastes an extra warm-up event.

Second entry starts at 10 (WT), left over from the exit:

Event Actual Before Predict Correct? After
1 T 10 (WT) T 11
2 T 11 (ST) T 11
3 T 11 (ST) T 11
4 T 11 (ST) T 11
5 NT 11 (ST) T 10

Correct = 4 of 5 ⇒ 80%. The hysteresis has now "learned" the loop: only the exit misses. See the state figure below.

Figure — Branch prediction (static and dynamic)

Exercise 3.2

A loop runs 100 taken iterations then 1 not-taken exit, and the whole loop is entered many times. Using a warmed-up 2-bit counter, how many mispredictions per 101-event pass, and what is the steady-state accuracy?

Recall Solution

Once warmed up, the counter sits at 11 (ST) throughout the 100 taken iterations — all correct. The single exit NT mispredicts (predicted T at 11), dropping the counter to 10. On re-entry the very first taken event pushes it back to 11, so no cold-start penalty on subsequent passes.

Mispredictions per pass = 1 (the exit only). This is the classic "2-bit predictors nail long loops" result: the longer the loop, the more the single exit miss gets amortised.


Level 4 — Synthesis

Exercise 4.1

You must choose between two predictors for a workload where branches are 25% of instructions and the misprediction penalty is 10 cycles.

  • Predictor A (2-bit bimodal): 6% mispredict rate, negligible extra area.
  • Predictor B (correlating, 2-level): 2.5% mispredict rate, but adds a global-history lookup that raises the base CPI from 1.00 to 1.05 (extra pipeline stage for the second table access).

Which gives lower CPI?

Recall Solution

Predictor A: Predictor B: the base cost is now 1.05, not 1.00: Compare: . Predictor B wins despite its higher base cost, because the misprediction savings (, a drop of ) outweigh the base penalty. Net advantage CPI.

Exercise 4.2

For the same workload, find the break-even mispredict rate for Predictor B — the accuracy at which B and A tie. Above this, B is not worth its extra base cost.

Recall Solution

Set the two CPIs equal: So B must keep its mispredict rate below 4% to justify its 0.05-CPI overhead. At exactly 4% they tie; at the given 2.5% B is comfortably ahead.


Level 5 — Mastery

Exercise 5.1

Consider the nested pattern that motivates correlating predictors:

if (a > 0) {      // B1
    if (b > 0) {  // B2 — only runs when B1 taken
        ...
    }
}

Over 1000 runs, a > 0 is true 50% of the time. When B1 is taken (500 runs), b > 0 is true 90% of the time; the other 500 runs B2 never executes. A bimodal (per-branch, no history) predictor for B2 must pick one fixed bias. A correlating predictor can key on the outcome of B1. Compute the best-case accuracy of each on B2's executed instances, and explain the gap.

Recall Solution

B2 only executes on the 500 runs where B1 was taken. Of those, it is taken 90%.

Bimodal on B2: it sees only the 500 executed instances (B2 is skipped otherwise, so no update). Best fixed bias = predict Taken (the majority). Accuracy on executed instances: Here bimodal already does fine on B2 alone, because B2's own history is a clean 90%-taken stream.

Where correlation actually pays is a different, aliasing-driven case. Suppose instead B2's outcome were perfectly determined by B1: whenever B1 taken ⇒ B2 taken, whenever (hypothetically) B1 not-taken but B2 still reached ⇒ B2 not-taken. Then the correlating predictor, keyed on the 1-bit global history of B1, reaches: while bimodal, forced to blend the two sub-streams into one counter, sits at the majority mix. The gap = the mutual information between B1 and B2. When a branch's outcome is predictable from recent branches, only a history-indexed (correlating) predictor can exploit it; a per-address bimodal counter throws that context away.

Exercise 5.2

Design decision: a 2-level predictor uses a global history register of bits, indexing a table of counters, each 2 bits. (a) How many bits of storage? (b) If doubling from 8 to 9 reduces mispredicts from 3.0% to 2.7% on a machine with 25% branches and a 14-cycle penalty, is the extra table worth it in CPI terms? (Assume base CPI unchanged.)

Recall Solution

(a) Table has entries, each 2 bits: storage bits. For : bits (64 bytes). For : bits (128 bytes).

(b) CPI contribution from mispredicts .

  • At : added CPI.
  • At : added CPI.

Savings CPI for doubling the table (64 → 128 bytes). Whether that is "worth it" is a policy call, but the marginal gain is real and cheap in storage; the classic diminishing-returns curve means the next doubling (h=9→10) will save even less. Relate this to Cache Performance — same "double the table, shrink the benefit" shape.

Recall Quick self-check (cloze)

The three factors multiplied in the CPI penalty term are ==, , and Penalty. Hysteresis in a 2-bit counter costs you accuracy on a cold, short loop but wins on a long, warm loop. Correlating predictors only beat bimodal when a branch correlates with recent branch history==.

Which two events does a 1-bit predictor always miss on a loop?
The first iteration (cold start) and the exit (loop end).
Why can a fancier predictor still lose in total CPI?
Its extra lookup can raise the base CPI for every instruction, outweighing the mispredict savings.