Visual walkthrough — Tournament and TAGE predictors
This page rebuilds one single result in pictures: how does TAGE decide which of its many tables gets to predict a branch? We will earn every symbol before we use it. By the end you will be able to trace a branch through the whole machine on paper.
If a word here feels unexplained, it is built in an earlier step. Nothing is assumed from the parent note — we start below zero.
Step 1 — What is a branch, and what is "history"?
WHAT. A branch is an instruction like if (x > 0) jump. Its outcome is one of two things: T (taken, we jump) or NT (not taken, we fall through). We label the address of the branch instruction its PC (Program Counter — literally which line of code we are at).
WHY. Before predicting whether we take a branch, we need a written record of what recently happened. That record is the Global History Register (GHR): a row of bits, newest on the right, where each bit is one past branch outcome (1 = T, 0 = NT).
PICTURE. Look at the figure. The GHR is a sliding row of bits. Every time any branch resolves, we shove its outcome in on the right and the oldest bit falls off the left — like a queue.
Step 2 — Why not just one history length? (the core tension)
WHAT. We must pick how many bits of GHR to feed the predictor. Call that number (the history length).
WHY. Here is the tension the whole design solves:
- A loop counter branch (T,T,T,T,NT) only needs the last few outcomes — small (say ).
- A correlated branch (
if a>0far away decidesif b>0here) needs many outcomes back — large (say ).
If you fix one , you are wrong for the other kind of branch: too short underfits (misses the pattern), too long dilutes (needs impossibly many table entries to cover every history combination).
PICTURE. The figure shows the same branch fed by a short window vs a long window. Short window = few possible patterns, learns fast, but blind to distant causes. Long window = sees the cause, but there are astronomically many patterns to memorise.
The resolution: keep many predictors, each at a different , and let them compete. That is the geometric ladder we build next. See also 5.3.8-Two-level-adaptive-predictors for the single-length ancestor.
Step 3 — The geometric ladder of tables
WHAT. TAGE holds a stack of small tables. The bottom is the base predictor (uses no history — pure PC bias). Above it sit tagged tables , each assigned a history length that grows geometrically:
Term by term: is how many GHR bits table looks at. "Geometric" means each length is roughly a fixed multiple of the one below (here ), not a fixed addition.
WHY geometric and not ? Because branch correlations live at wildly different distances. Doubling covers a huge span () with only 4 tables. If we added each time we would need many more tables to reach , wasting hardware. Doubling gives broad coverage cheaply — that is the whole point of the "Geometric" in TAGE.
PICTURE. A staircase: on the ground (no window), then each step up peers through a window twice as wide.
Ratio check: . ✓
Step 4 — How one table is addressed: index and tag
WHAT. Each tagged table has rows. To find this branch's row we compute an index — an address into the table — by hashing (scrambling together) the PC and the first bits of GHR:
Because many different (PC, history) combos can scramble to the same row (a collision), each row also stores a tag: a second, independent hash of (PC, history) that we compare to confirm "yes, this row really belongs to me."
WHY a tag at all? Without it, two unrelated branches landing in the same row would silently corrupt each other's prediction. The tag is a fingerprint: if the stored tag ≠ the fingerprint we just computed, this row is not ours — treat the table as not matching.
PICTURE. One row = three fields: the tag (fingerprint), a prediction counter (which way to guess), and a useful bit (built in Step 7). The index picks the row; the tag confirms it.
Recall Why does the base
have no tag? is indexed by PC alone and always answers (it is the safety net). It can never "not match", so there is nothing to confirm — no tag needed. ::: Because is a plain PC-indexed 2-bit counter that must ALWAYS supply a fallback prediction, so it can't decline — a tag (which lets a table say "not me") would be meaningless.
Step 5 — The prediction: longest matching table wins
WHAT. Now the central result. On a branch we:
- Compute all indices at once (in parallel).
- Read each row and compare its stored tag to the freshly-computed fingerprint.
- Among all tables whose tag matches, pick the one with the largest (longest history). Call it the provider.
- Output the provider's counter sign: T if , else NT.
- If no tagged table matches, the provider is .
WHY longest? A longer history that still recognises this situation has conditioned its guess on strictly more context — it is the most specific witness. A short table might match by coincidence; a long matching table has seen this precise sequence and survived. Specificity beats generality when it applies, and the tag guarantees it applies.
PICTURE. Four tables light up green (match) or grey (miss). Here and match; miss. The arrow crowns the provider because .
Step 6 — Edge & degenerate cases (all of them)
WHAT. Four situations must never surprise us. Each is drawn in the figure panel.
(a) No table matches — brand-new branch, empty tables. Provider . We still emit a guess (its PC bias). Never a crash.
(b) Only has ever seen this branch — same as (a): use base. This is the cold start every branch begins in.
(c) Two tables match, longer one is wrong — we still trust the longer (Step 5 rule), but Step 7's allocation will grow a still-longer table to fix it. Being wrong is how TAGE learns which length it needs.
(d) Counter exactly at the boundary — predicts T (rule is ). A counter that saturates at or cannot overflow; it just stays pinned — this is why it is called a saturating counter, and it prevents a single fluke from flipping a confident branch.
PICTURE. Four mini-panels, one per case, showing the provider chosen (or the saturated counter refusing to move).
Step 7 — Update: reward the provider, allocate on failure, and the useful bit
WHAT. When the true outcome arrives, TAGE does three things.
-
Update the provider counter. Move it toward the truth: if actual = T, do ; if actual = NT, . The are the saturation — the counter never leaves .
-
On a wrong prediction, allocate a fresh entry in some longer table with (provider was ). Give a longer history a chance — the current length clearly wasn't enough (this is exactly edge case (c)).
-
The useful bit . Set on a provider entry when it predicted correctly and the next-shorter matching table would have been wrong — proof this entry earned its keep. Periodically all are reset toward 0; entries stuck at are the ones we overwrite when we need room. This is victim selection: forget the entries that never help.
WHY allocate longer, never shorter? If a long matching table was already wrong, a shorter one (less context) has no chance of doing better — going the other way is hopeless. Growth is the only direction that adds information.
PICTURE. Left: provider counter nudged toward the true outcome (saturating). Right: a misprediction spawns a new tagged entry one rung up the ladder.
The one-picture summary
The whole life of one prediction: compute indices → check tags → longest match provides → predict from its counter → on resolution, update / allocate longer / manage useful bits. The staircase, the fingerprint match, the crowned provider, and the feedback arrows all in one frame.
Recall Feynman retelling — tell it back in plain words
Imagine a branch walks up to a row of witnesses. Each witness has watched a different amount of the past: one glanced at the last 4 events, another at the last 8, then 16, then 32. Every witness also carries a fingerprint card so it can honestly say "I actually recognise this exact scene" or stay quiet. TAGE listens only to witnesses who recognise the scene, and among those it believes the one who watched the most history — because that witness's guess is built on the most context. If nobody recognises the scene, an ever-present ground-floor witness (the base predictor) gives a rough PC-based hunch so we always have an answer. When the truth comes out, we nudge the chosen witness's confidence toward what really happened (but never past its limits — that's the saturating counter). If even our most-experienced witness got it wrong, we recruit a new witness with an even longer memory, because clearly we needed to look further back. And witnesses who never once made a difference get quietly retired to free up seats. That loop — recognise, trust the longest, correct, grow longer on failure — is the entire engine, and it climbs past 95% accuracy on real programs. Next stop: 5.3.11-Branch-target-bufers tells us where a taken branch jumps, and 5.4.2-Speculative-execution shows what all this guessing buys us.
Related builds: 5.3.9-Gshare-and-local-predictors, 7.2.5-Cache-coherence-and-branch-predictors.