5.4.5Memory Hierarchy & Caches

Replacement policies (LRU, FIFO, random)

4,817 words22 min readdifficulty · medium1 backlinks

Overview

When a cache is full and a new block needs to be loaded, the cache controller must decide which existing block to evict. This decision is made by the replacement policy. The three fundamental strategies are Least Recently Used (LRU), First-In First-Out (FIFO), and Random.


Why Replacement Policies Matter

The Problem: Cache capacity < Memory size. Temporal locality means recently-used data is likely to be used again. Spatial locality means nearby data is likely to be used soon. A replacement policy exploits these patterns to minimize miss rate.

Performance Impact:

  • Miss rate directly affects average memory access time (AMAT): AMAT=Hit Time+Miss Rate×Miss Penalty\text{AMAT} = \text{Hit Time} + \text{Miss Rate} \times \text{Miss Penalty}
  • A 1% difference in miss rate can mean 10-20% performance difference in memory-bound applications
  • Replacement policy affects miss rate but also has hardware cost

LRU (Least Recently Used)

How LRU Works

Mechanism:

  1. Every cache access updates a timestamp or reorders a recency list
  2. On eviction, choose the block with the oldest timestamp / at the tail of the list
  3. On hit or miss (after loading), mark that block as most recently used

Why this approach? Temporal locality: recently-accessed data is likely to be accessed again soon. The block that hasn't been touched longest has the lowest probability of being needed next.

Derivation of LRU Behavior

Consider a 2-way set-associative cache with blocks A and B in set.

Access sequence: A, B, A, C

Access Action Recency Order (MRU → LRU) Why this step?
A Load A to way 0 [A, -] First access, empty cache
B Load B to way 1 [B, A] B becomes MRU, A is now LRU
A Hit on A [A, B] A becomes MRU again, B is now LRU
C Evict B, load C to way 1 [C, A] B is LRU, so we replace it. C becomes MRU

Key insight: Each access reorders the recency structure. The block that hasn't been touched longest is always at the "cold" end.

LRU Implementation

Challenge: Tracking recency has hardware cost.

Exact LRU (for small n):

  • Counter method: Each block has a timestamp counter. On access, set counter to global time; increment global time. Evict block with smallest counter.
    • Cost: n counters of log2(time)\log_2(\text{time}) bits each
  • Pseudo-LRU (tree-based): Use n1n-1 bits to build a binary tree. Each bit indicates which subtree was accessed more recently. On access, flip bits along path from root to block.
    • Cost: Only n1n-1 bits for n-way set
    • Approximation: doesn't track exact LRU, but close enough

For 4-way set: Exact LRU needs 4 × 2 = 8 bits (2-bit counters). Pseudo-LRU needs 3 bits.


FIFO (First-In First-Out)

How FIFO Works

Mechanism:

  1. Maintain a queue pointer or timestamp indicating insertion order
  2. On eviction, choose the block that entered the cache first
  3. On hit, do nothing to the order (this is key difference from LRU)

Why FIFO? Simplicity. No need to track accesses, only insertion order.

Derivation of FIFO Behavior

Consider the same 2-way set, access sequence: A, B, A, C

Access Action Queue Order (Head → Tail) Why this step?
A Load A [A, -] A enters first
B Load B [A, B] B enters second (queue now [A, B])
A Hit on A [A, B] Order unchanged — FIFO ignores hits
C Evict A, load C [B, C] A entered first, so evict A despite recent hit

Critical difference from LRU: The hit on A doesn't move A to the back of the queue. FIFO is oblivious to access patterns after insertion.

FIFO Implementation

Hardware: Single log2n\lceil \log_2 n \rceil-bit counter per set. Incredibly cheap.

For 4-way set: 2-bit counter. For 16-way: 4-bit counter.

Belady's Anomaly


Random Replacement

How Random Works

Mechanism:

  1. Use a pseudorandom number generator (PRNG) or linear feedback shift register (LFSR)
  2. On eviction, generate random index i[0,n1]i \in [0, n-1]
  3. Evict block at way ii

Why random? When workload is unpredictable or adversarial, any deterministic policy can be exploited. Random avoids worst-case patterns.

Derivation of Random Behavior

For an n-way set, each block has eviction probability:

P(evict block i)=1nP(\text{evict block } i) = \frac{1}{n}

Expected number of accesses before evicting a specific block (if it's not accessed again):

E[lifetime]=n evictionsE[\text{lifetime}] = n \text{ evictions}

Why this formula? Each eviction is an independent trial with success probability 1n\frac{1}{n}. This is a geometric distribution: expected number of trials = 1p=n\frac{1}{p} = n.

Random Implementation

Hardware: SmallLFSR (e.g., 4-bit for 16-way set) or use low bits of cycle counter. Extremely cheap: ~10 gates.


Comparison: LRU vs FIFO vs Random

| Policy | Miss Rate | Hardware Cost | Anomalies | Best For | |--------|---------------|-----------|----------| | LRU | Lowest for most workloads | Highest (counters/trees) | None (stack algorithm) | Temporal locality | | FIFO | Medium | Lowest (single counter) | Belady's Anomaly | Streaming / sequential access | | Random | Medium-high | Very low (LFSR) | None (probabilistic) | Adversarial / unpredictable workloads |

Why These Differences?

LRU exploits temporal locality:

  • Recent accesses predict future accesses
  • Best when working set fits in cache and exhibits reuse
  • Cost: Must update state on every access

FIFO ignores access patterns:

  • Only tracks insertion order
  • Works okay for sequential scans (streaming data)
  • Fails when blocks are reused after initial load
  • Cost: Update only on evictions

Random avoids worst-case:

  • No pathological access patterns can cause100% miss rate
  • Performance is average across all patterns
  • Cost: Minimal hardware, no state updates

Worked Example: Detailed Trace Comparison

Setup: 4-way set-associative cache, access sequence:

A, B, C, D, E, B, A, B, F, G

Let's trace all three policies:

LRU Trace

Access Cache State Recency Order (MRU→LRU) Hit/Miss Why this step?
A [A, -, -, -] [A] Miss Cold start, load A
B [A, B, -, -] [B, A] Miss Load B, A ages by 1
C [A, B, C, -] [C, B, A] Miss Load C and B age
D [A, B, C, D] [D, C, B, A] Miss Load D, cache now full
E [E, B, C, D] [E, D, C, B] Miss Evict A (LRU), load E
B [E, B, C, D] [B, E, D, C] Hit B moves to MRU
A [E, B, A, D] [A, B, E, D] Miss Evict C (LRU), load A
B [E, B, A, D] [B, A, E, D] Hit B moves to MRU
F [E, B, A, F] [F, B, A, E] Miss Evict D (LRU), load F
G [G, B, A, F] [G, F, B, A] Miss Evict E (LRU), load G

Total: 8 misses, 2 hits

FIFO Trace

Access Cache State Queue (head→tail) QueuePtr Hit/Miss Why this step?
A [A, -, -, -] [A] 1 Miss Load A to way 0
B [A, B, -, -] [A, B] 2 Miss Load B to way 1
C [A, B, C, -] [A, B, C] 3 Miss Load C to way 2
D [A, B, C, D] [A, B, C, D] 0 Miss Load D to way 3
E [E, B, C, D] [B, C, D, E] 1 Miss Evict A (ptr=0), load E
B [E, B, C, D] [B, C, D, E] 1 Hit No queue change
A [E, A, C, D] [C, D, E, A] 2 Miss Evict B (ptr=1), load A
B [E, A, B, D] [D, E, A, B] 3 Miss Evict C (ptr=2), load B
F [E, A, B, F] [E, A, B, F] 0 Miss Evict D (ptr=3), load F
G [G, A, B, F] [A, B, F, G] 1 Miss Evict E (ptr=0), load G

Total: 9 misses, 1 hit

Note: FIFO evicts B at step 7even though B was just accessed (hit). This is why FIFO mises on the second B access.

Random Trace

Assume PRNG outputs: [-, -, -, 1, -, 0, 3, 2, 1]

| Access | Cache State | Random Way | Hit/Miss | Why this step? | |--------|-------------|------------|----------------| | A | [A, -, -, -] | - | Miss | Load A to way 0 | | B | [A, B, -, -] | - | Miss | Load B to way 1 | | C | [A, B, C, -] | - | Miss | Load C to way 2 | | D | [A, B, C, D] | - | Miss | Load D to way 3 | | E | [A, E, C, D] | 1 (B) | Miss | Evict B (random), load E | | B | [A, E, C, D] | - | Miss | Load B to way 1 (just evicted!) | | A | [A, E, C, D] | - | Hit | A still in cache | | B | [A, E, C, B] | 3 (D) | Miss | Evict D (random), load B | | F | [A, E, F, B] | 2 (C) | Miss | Evict C (random), load F | | G | [A, G, F, B] | 1 (E) | Miss | Evict E (random), load G |

Total: 9 misses, 1 hit

Random happened to evict B right before it was needed again (unlucky), but avoided some of LRU's smart evictions by chance.

Summary

Miss rates:

  • LRU: 80% (8/10 misses) — best performance
  • FIFO: 90% (9/10 misses) — worst here due to evicting recently-hit B
  • Random: 90% (9/10 misses) — comparable to FIFO

Key observation: LRU's advantage comes from the two hits on B. By keeping recently-accessed blocks, LRU avoids re-fetching B after the first hit. FIFO and Random don't track recent access, so they evict B and suffer mises.


Recall Explain to a 12-year-old

Imagine you have a tiny backpack that can only hold 4 school books, but you need to access 10 different books throughout the day.

LRU (Least Recently Used): Every time you use a book, you push it to the front of your backpack. The book at the very back is the one you haven't touched in the longest time. When you need a new book and your backpack is full, you remove the book at the back. This works great because you usually need the same books over and over, so keeping the ones you just used makes sense!

FIFO (First-In First-Out): You arrange your books in the order you first put them in. When you need a new book, you always remove the book you put in first, even if you just used it a minute ago! It's like a conveyor belt — first book in is the first book out. This is super easy to keep track of (just remember which book came first), but sometimes you remove books you actually need soon.

Random: You close your eyes and randomly pull out any book when you need space. No strategy at all! Sometimes you get lucky and remove book you won't need. Sometimes you remove a book you're about to use again. On average, it works okay, and you don't need to remember anything.

The best strategy depends on your pattern: if you reuse the same books a lot (like textbooks for homework), LRU wins. If you're just reading books once in order (like a library book list), FIFO is fine. If someone keeps changing which books you need in tricky ways, Random avoids being tricked.



Advanced: Practical Hybrid Policies

Real processors often use approximations:

Pseudo-LRU (PLRU)

  • Tree-based bits to approximate LRU ordering
  • Intel Core, AMD Ryzen use PLRU for L2/L3 caches
  • Cost: n1n-1 bits for n-way, vs. nlognn \log n for true LRU

Not Recently Used (NRU)

  • Single reference bit per block, cleared periodically
  • Evict any block with ref bit = 0
  • Used in some TLBs and page tables

Clock Algorithm

  • Circular buffer with a hand pointer
  • On eviction, scan clockwise, clear ref bits, evict first block with ref=0
  • Used in OS page replacement (approximates LRU)

Connections


#flashcards/hardware

What is a cache replacement policy and why is it needed? :: A policy that decides which block to evict when the cache is full and a new block must be loaded. Needed because cache capacity is limited and we must choose which blocks to keep to minimize miss rate.

What does LRU stand for and what does it evict?
Least Recently Used. LRU evicts the block that has not been accessed for the longest time.
Why does LRU generally have the lowest miss rate?
LRU exploits temporal locality — recently accessed data is likely to be accessed again soon, so keeping recent blocks maximizes hit probability.

What is the hardware cost trade-off for LRU? :: LRU requires tracking recency for every access (counters or trees), making it the most expensive policy in terms of hardware complexity.

What does FIFO stand for and what does it evict?
First-In First-Out. FIFO evicts the block that was loaded earliest, treating the cache as a queue.
Why is FIFO cheaper than LRU?
FIFO only needs a single counter per set to track insertion order, and doesn't update on cache hits, reducing hardware and energy cost.
What is Belady's Anomaly?
A phenomenon where increasing cache capacity can actually increase miss rate under FIFO replacement for certain access patterns.
Why doesn't LRU suffer from Belady's Anomaly?
LRU is a stack algorithm — the contents of a k-way cache are a subset of a (k+1)-way cache under the same access sequence, guaranteeing monotonic miss rate improvement.
What is the Random replacement policy?
A policy that evicts a uniformly random block from the set using a PRNG or LFSR, with no history tracking.
When is Random replacement better than deterministic policies?
In adversarial or highly unpredictable workloads where any deterministic pattern can be exploited, and for hardware simplicity.
What is the eviction probability for each block under Random replacement in an n-way cache?
1/n for each block (uniform distribution).
What is Pseudo-LRU (PLRU)?
An approximation of LRU using a binary tree of bits (n-1 bits for n-way) that indicates which subtree was accessed more recently, reducing hardware cost.
How does FIFO behave differently from LRU when a block is accessed (hit)?
FIFO does not change the eviction order on a hit — the queue order remains based on insertion time. LRU moves the accessed block to the most-recently-used position.
What is the recency counter update rule for LRU?
On access to block i, set Recency_i = 0 (MRU). Increment all other blocks' recency counters (they age). Evict the block with maximum recency.
What is the formula for AMAT (Average Memory Access Time)?
AMAT = Hit Time + (Miss Rate × Miss Penalty). Replacement policy affects miss rate.
What is a stack algorithm in the context of cache replacement?
A policy where the contents of a size-k cache are a subset of a size-(k+1) cache for the same access sequence, ensuring monotonic miss rate improvement with capacity.
What is the hardware implementation of FIFO?
A single modulo-n counter (queue pointer) per set that cycles through ways [0, n-1], advancing on each eviction.
What is the hardware implementation of Random?
A small PRNG or LFSR that generates a random way index [0, n-1] on each eviction.
In a 4-way cache with access sequence [A, B, C, D, E], which block does LRU evict on access E?
A (the least recently used block at that point).
In the same scenario, which block does FIFO evict?
A (the first block loaded, since the queue is [A, B, C, D]).
Why might FIFO have higher miss rate than LRU for workloads with reuse?
FIFO can evict recently-accessed blocks just because they were loaded early, ignoring the recent access pattern that suggests they'll be needed again soon.

Concept Map

needs to

decided by

strategy

strategy

strategy

exploits

reduces

affects

drives

maintains

has

Cache full

Evict a block

Replacement policy

LRU least recently used

FIFO first-in first-out

Random

Temporal locality

Miss rate

Average memory access time

Recency ordering

Hardware cost and complexity

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, jab tumhara cache full ho jata hai aur ek naya block load karna padta hai, tab controller ko decide karna padta hai ki purane blocks me se kaunsa nikaal dein — isko hi eviction bolte hain, aur ye decision jis rule se hota hai use replacement policy kehte hain. Simple example samjho: tumhare study desk pe sirf 4 books ki jagah hai, ab 5th book chahiye toh ek toh hatani padegi na? LRU bolta hai jo book sabse lambe time se nahi chhui use hatao, FIFO bolta hai jo sabse pehle rakhi thi use hatao, aur Random bolta hai bas koi bhi utha ke phenk do. Har policy ke apne trade-offs hain — kitna acha perform karti hai, kitna hardware cost aata hai, aur kitni complex hai.

Ab ye matter kyun karta hai? Kyunki cache ki size limited hoti hai (cost aur power ki wajah se), toh kaunse blocks rakhne hain ye decision seedha tumhare miss rate ko affect karta hai. Aur miss rate ka direct impact hota hai AMAT pe, jiska formula hai: AMAT = Hit Time + Miss Rate × Miss Penalty. Yaad rakho, sirf 1% ka miss rate difference bhi memory-heavy applications me 10-20% performance ka farak la sakta hai — toh ye chhoti si decision actually bahut bada impact rakhti hai.

LRU ka core intuition ye hai ki "agar tumne kuch der se koi cheez use nahi ki, toh probably wo jaldi chahiye bhi nahi hogi" — ye temporal locality ka faayda uthata hai. Har access pe ek recency order update hota hai, aur jo block sabse "cold" end pe hai (sabse purana) usko evict kar dete hain. Practically exact LRU implement karna mehenga hota hai kyunki har block ke liye counters maintain karne padte hain, isliye engineers Pseudo-LRU (tree-based) use karte hain jo thode kam bits me kaam chala leta hai aur "close enough" result deta hai. Bas yehi balance — accuracy vs hardware cost — real-world design me sabse important baat hai.

Go deeper — visual, from zero

Test yourself — Memory Hierarchy & Caches

Connections