5.4.5 · D4Memory Hierarchy & Caches

Exercises — Replacement policies (LRU, FIFO, random)

4,079 words19 min readBack to topic

This page is a self-test workout for Replacement policies (LRU, FIFO, Random). Each problem is graded by cognitive level — from just recognizing what a policy does, up to designing and proving things about them.

Every solution is hidden inside a collapsible [!recall]- callout. Try first, then reveal. After each level there is a [!mistake] warning about the classic trap at that level.

Prerequisites worth having open: 5.4.01-Cache-organizationand-addressing, Temporal-and-spatial-locality, Working-set-model.


Level 1 — Recognition

Exercise 1.1 (L1)

A cache set is full. A new block must be loaded. Which existing block does each policy evict? For each of LRU, FIFO, Random, state the single sentence rule.

Recall Solution
  • LRU: evict the block not accessed for the longest time (oldest use).
  • FIFO: evict the block loaded earliest (oldest insertion), ignoring how recently it was used.
  • Random: evict a uniformly random block, tracking no history at all.

Exercise 1.2 (L1)

On a hit, which of the three policies updates its bookkeeping, and which do nothing?

Recall Solution
  • LRU — updates: the hit block becomes most recently used (reordered to the front).
  • FIFO — does nothing: insertion order is unchanged by hits.
  • Random — does nothing: there is no history to update.

This one line is the whole difference between LRU and FIFO. LRU reacts to access; FIFO only reacts to insertion.

Exercise 1.3 (L1)

A 4-way set uses exact LRU with 2-bit counters per block. How many bookkeeping bits per set? A second cache uses tree pseudo-LRU for the same 4-way set — how many bits, and why that number?

Recall Solution
  • Exact LRU: one 2-bit counter per way bits.
  • Tree pseudo-LRU: bits.

FIFO for the same set needs only bits (one pointer for the whole set).

Why bits for the tree? Picture the ways as the four leaves of a small binary tree. To pick a single leaf you walk down from the root making one left/right choice at each internal node: first choice picks the left pair or the right pair, second choice picks one way inside that pair. A binary tree with leaves has exactly internal nodes, and each internal node stores one bit ("which child was touched more recently — go the other way to evict"). So leaves internal nodes bits. On every access you flip the bits along the root-to-leaf path to point away from the block just used; on eviction you follow the bits to reach the pseudo-oldest leaf. That is why bits suffice instead of the bits exact LRU needs.


Level 2 — Application

Exercise 2.1 (L2)

A 2-way set, initially empty, uses LRU. Trace the access sequence: A B A C B. Report the final cache contents and count the misses.

Recall Solution

Recency shown as [MRU → LRU] (freshest → eviction candidate).

Access Hit/Miss Cache Recency (MRU→LRU)
A [A, –] [A]
B [A, B] [B, A]
A [A, B] [A, B]
C ✘ evict B [A, C] [C, A]
B ✘ evict A [C, B] [B, C]

Misses = 4 (only the second A is a hit). Final contents: {C, B}. Note the C step: B was LRU (A had just been re-hit), so B is evicted — not A.

Exercise 2.2 (L2)

Same 2-way set and same sequence A B A C B, but now use FIFO. Final contents and miss count?

Recall Solution

Queue shown [Head(oldest) → Tail(newest)]. Hits leave the queue untouched.

Access Hit/Miss Cache Queue
A [A, –] [A]
B [A, B] [A, B]
A [A, B] [A, B]
C ✘ evict A [C, B] [B, C]
B [C, B] [B, C]

Misses = 3. Final contents: {C, B}. The C step evicts A — the oldest insertion — even though A was just hit. That saved B, so the final B is a hit. Here FIFO beats LRU (3 vs 4 misses) purely by luck of pattern.

Exercise 2.3 (L2)

Compute AMAT (Average Memory Access Time) for a cache with Hit Time = 2 ns, Miss Penalty = 100 ns, and a Miss Rate of . Then, if a better policy lowers the miss rate to , what is the new AMAT and the percentage improvement?

Recall Solution

AMAT stands for Average Memory Access Time — the average number of time units one memory access costs, blending fast hits and slow misses.

Why the formula decomposes this way. Every access first tries the cache, so it always pays the Hit Time. A fraction of accesses (the Miss Rate) additionally miss and must fetch from the slower level, paying the Miss Penalty on top. Averaging over all accesses, the expected extra cost is (fraction that miss) (cost of a miss) Miss Rate Miss Penalty. Add the guaranteed hit cost and you get: This is just an expected value: base cost everyone pays, plus a penalty weighted by how often it strikes.

Plugging in: Improvement faster average access. A "mere" 1-percentage-point drop in miss rate cut average access time by one-sixth — exactly why replacement policy matters. See 5.4.01-Cache-organizationand-addressing for where Hit Time comes from.


Level 3 — Analysis

Exercise 3.1 (L3)

A 3-way set uses LRU. Trace A B C A B D E B A. Give the miss count and the final set.

Recall Solution

Recency [MRU→LRU]. Full set = 3 blocks.

Access H/M Cache Recency
A {A} [A]
B {A,B} [B,A]
C {A,B,C} [C,B,A]
A {A,B,C} [A,C,B]
B {A,B,C} [B,A,C]
D ✘ evict C {A,B,D} [D,B,A]
E ✘ evict A {B,D,E} [E,D,B]
B {B,D,E} [B,E,D]
A ✘ evict D {B,E,A} [A,B,E]

Misses = 6. Final set: {B, E, A}. Watch the D step: LRU order was [B,A,C], so C (LRU) dies. Then E kicks A (A had aged to LRU). Then A returns as a miss — LRU discarded it one step too early here.

Exercise 3.2 (L3)

Same 3-way set, same sequence A B C A B D E B A, but FIFO. Miss count and final set? Compare to Exercise 3.1.

Recall Solution

Queue [Head→Tail], hits frozen.

Access H/M Cache Queue
A {A} [A]
B {A,B} [A,B]
C {A,B,C} [A,B,C]
A {A,B,C} [A,B,C]
B {A,B,C} [A,B,C]
D ✘ evict A {B,C,D} [B,C,D]
E ✘ evict B {C,D,E} [C,D,E]
B {C,D,E}→{E,D,B}* [D,E,B]
A ✘ evict D {E,B,A} [E,B,A]

*At the B step the queue head is C, so C is evicted, B loaded into that slot. Misses = 7. Final set: {E, B, A}. Comparison: LRU = 6 misses, FIFO = 7. Here LRU wins because it exploited that A and B were reused (temporal locality — see Temporal-and-spatial-locality), while FIFO evicted A blindly by insertion order.

Exercise 3.3 (L3)

Explain in one paragraph why LRU can never suffer Belady's Anomaly, using the idea of an inclusion property.

Recall Solution

LRU is a stack algorithm: at any moment, the set of blocks a cache of size holds is always a subset of what a cache of size would hold on the same trace. Formally, order all blocks by recency in one big stack; a size- cache holds exactly the top of that stack. Growing the cache to just adds the next block down — it never removes anything the smaller cache kept. So any block that was a hit with frames is still a hit with frames. Hits can only be added, never lost ⇒ misses are monotonically non-increasing in capacity. FIFO lacks this property because its "stack" (insertion order) does not nest as capacity grows.


Level 4 — Synthesis

Exercise 4.1 (L4)

Reproduce Belady's Anomaly for FIFO. Using the classic reference string 1 2 3 4 1 2 5 1 2 3 4 5 with a fully-associative cache (one set), show that 3 frames give fewer misses than 4 frames. Report both miss counts.

Recall Solution — 3 frames

Queue [Head→Tail]. ✘ = miss.

Ref H/M Frames Evict
1 {1}
2 {1,2}
3 {1,2,3}
4 {2,3,4} 1
1 {3,4,1} 2
2 {4,1,2} 3
5 {1,2,5} 4
1 {1,2,5}
2 {1,2,5}
3 {2,5,3} 1
4 {5,3,4} 2
5 {5,3,4}

3-frame misses = 9.

Recall Solution — 4 frames
Ref H/M Frames Evict
1 {1}
2 {1,2}
3 {1,2,3}
4 {1,2,3,4}
1 {1,2,3,4}
2 {1,2,3,4}
5 {2,3,4,5} 1
1 {3,4,5,1} 2
2 {4,5,1,2} 3
3 {5,1,2,3} 4
4 {1,2,3,4} 5
5 {2,3,4,5} 1

4-frame misses = 10.

Result: 9 misses with 3 frames vs 10 misses with 4 frames — more cache, more misses. This is Belady's Anomaly. The figure below plots both curves so you can see the crossover.

Figure — Replacement policies (LRU, FIFO, random)

Exercise 4.2 (L4)

On the same reference string 1 2 3 4 1 2 5 1 2 3 4 5, run LRU with 3 frames and 4 frames. Confirm LRU obeys the stack property (misses do not increase with more frames).

Recall Solution — LRU, 3 frames

Recency [MRU→LRU]. Full set = 3 blocks.

Ref H/M Frames Recency (MRU→LRU) Evict
1 {1} [1]
2 {1,2} [2,1]
3 {1,2,3} [3,2,1]
4 {2,3,4} [4,3,2] 1
1 {3,4,1} [1,4,3] 2
2 {4,1,2} [2,1,4] 3
5 {1,2,5} [5,2,1] 4
1 {1,2,5} [1,5,2]
2 {1,2,5} [2,1,5]
3 {2,5,3} [3,2,5] 1
4 {5,3,4} [4,3,5] 2
5 {5,3,4} [5,4,3]

Count the ✘ rows: refs 1,2,3,4 (4 misses), then 1,2,5 (3 more = 7), then 3,4 (2 more = 9). The final 5 is a hit. LRU 3-frame misses = 9. The three ✔ rows are the mid-sequence hits on blocks 1 and 2 (steps 8, 9) and the final hit on 5 (step 12).

Recall Solution — LRU, 4 frames
Ref H/M Frames Recency (MRU→LRU) Evict
1 {1} [1]
2 {1,2} [2,1]
3 {1,2,3} [3,2,1]
4 {1,2,3,4} [4,3,2,1]
1 {1,2,3,4} [1,4,3,2]
2 {1,2,3,4} [2,1,4,3]
5 {1,2,4,5} [5,2,1,4] 3
1 {1,2,4,5} [1,5,2,4]
2 {1,2,4,5} [2,1,5,4]
3 {1,2,3,5} [3,2,1,5] 4
4 {1,2,3,4} [4,3,2,1] 5
5 {2,3,4,5} [5,4,3,2] 1

Count the ✘ rows: 1,2,3,4 (4) then 5 (5) then 3,4,5 (3 more = 8). LRU 4-frame misses = 8.

Check: 3-frame LRU = 9 misses, 4-frame LRU = 8 misses. Since , misses did not increase with capacity — the stack property holds, exactly as Exercise 3.3 predicts. Contrast the FIFO anomaly (9 → 10) with LRU's clean 9 → 8.


Level 5 — Mastery

Exercise 5.1 (L5)

Consider the repeating pattern A B A B A B …. On a 2-way set that already holds {A, B}, every access is a hit — no evictions ever. Now consider a 1-way (direct-mapped) version of the same set, i.e. one slot that both A and B compete for. What is the miss rate of the pattern A B A B … on the 1-way cache, and does the policy choice (LRU / FIFO / Random) change it?

Recall Solution

With 1 slot, A and B conflict on every access: loading A evicts B, loading B evicts A. Since consecutive accesses always differ (A, B, A, B…), every access is a miss. Policy is irrelevant: with only one candidate to evict, LRU, FIFO and Random all evict the same (only) block. Miss rate is for all three. Lesson: replacement policy only matters when there is a choice of victim, i.e. associativity . A pathological conflict (working set > ways) defeats every policy — see Working-set-model and Cache-conscious-programming for how software avoids this.

Exercise 5.2 (L5)

Expected-value analysis of Random. A 4-way set is full with blocks . Exactly one of them, say , is the block that will be needed next (after the current miss's new block is loaded). Assume is also the most-recently-used block. Under Random replacement, what is the probability we evict (the soon-to-be-needed block) and cause an extra future miss? Compare with ideal LRU.

Recall Solution

Random picks each of the 4 ways with equal probability, so Random makes the wrong choice of the time here.

Ideal LRU: we are told is the most-recently-used block. LRU always evicts the least-recently-used block, which is one of — never the MRU block. Therefore

Comparison: Random has a chance of throwing away the hot block; LRU has a chance. That gap — vs of self-inflicted extra misses — is exactly the payoff of tracking history. LRU spends hardware bits to buy this protection, and it pays off whenever temporal locality holds (the just-used block really is likely to be needed again).

Exercise 5.3 (L5)

Design synthesis. You must pick a replacement policy for the L1 data cache of a low-power embedded core: 4-way associative, tight bit budget, hard real-time latency requirement (every access must complete in a fixed number of cycles). Argue which policy to choose and justify against each requirement.

Recall Solution

Recommended: tree pseudo-LRU (or plain FIFO if bits are truly scarce).

  • Bit budget: exact LRU needs bits/set; tree pseudo-LRU needs bits/set; FIFO needs bits/set. Pseudo-LRU nearly matches exact-LRU miss rate at bits — a strong bits-vs-performance point.
  • Real-time latency: all three (LRU counter update, FIFO pointer, pseudo-LRU bit-flip) are O(1) constant-time in hardware — no policy stalls the pipeline, so the fixed-cycle requirement is met by any of them.
  • Miss rate: on locality-rich embedded workloads pseudo-LRU beats FIFO (which risks Belady-style bad phases) and beats Random's mis-evictions.
  • When FIFO wins: if silicon area is the dominant constraint and workloads are streaming (little reuse, so LRU's history buys nothing), FIFO's 2-bit cost is optimal. Verdict: choose tree pseudo-LRU — 3 bits, constant-time, near-LRU miss rate, no anomaly worries. Relate to write-behavior sizing in 5.4.03-Write-policies-(write-through,-write-back) and multi-core effects in 5.4.06-Cache-coherence-protocols.