ยง22.1โ€“22.3Cache Management โ€ฆ A Simple Policy: FIFO

Part I OSTEP pp. 243โ€“247 ยท ~4 min read

  • amat
  • optimal replacement policy
  • compulsory miss
  • capacity miss
  • conflict miss
  • belady's anomaly
  • stack property

With plenty of free memory, a fault means grab-a-free-page โ€” hey, Operating System, you did it again! Under memory pressure, though, someone must be evicted, and the chooser is the replacement policy โ€” historically one of the most consequential decisions in systems with tiny memories.

The Crux: How To Decide Which Page To Evict

How can the OS decide which page (or pages) to evict from memory? The replacement policy follows general principles โ€” plus tweaks to dodge corner cases.

22.1 Cache Management

Reframe: main memory holds a subset of all pages, so it is a cache for virtual pages. The goal โ€” minimize misses (fetches from disk), maximize hits โ€” is quantified by the average memory access time :

AMAT=TM+(PMissร—TD)(22.1)\mathit{AMAT} = T_M + (P_{\mathit{Miss}} \times T_D) \tag{22.1}

You always pay the memory cost; misses add the disk cost. And the disk cost is monstrous:

The tyranny of the disk: AMAT across hit rates (T_M = 100ns, T_D = 10ms)
miss rateAMATreading
90% hits10%โ‰ˆ 1 msdisk speed
99.9% hits0.1%โ‰ˆ 10.1 ยตs~100ร— faster
100% hits0%100 nsmemory speed
Dotted-underlined cells have explanations โ€” click one.

Avoid misses, or run at the rate of the disk. Hence: policy.

22.2 The Optimal Replacement Policy

To judge any policy, first meet the unbeatable one. Beladyโ€™s optimal policy (he called it MIN): evict the page that will be accessed furthest in the future. The intuition is airtight โ€” every other cached page gets referenced before that one, so keeping them serves more hits. Itโ€™s also unimplementable: the future is not generally known. (If you can build it, let the authors know; you can get rich together โ€” or end up like the cold-fusion scientists.)

Run it, one decision at a time:

Figures 22.1 + 22.2, live: the canonical stream 0,1,2,0,1,3,0,3,1,2,1 in a 3-page cache. Run OPT, then flip the chip to FIFO.
AccessHit/Miss?EvictResulting Cache State
โ–ถ step through the trace, or run it all

OPT: at the first eviction, the future says 0 comes almost immediately, 1 a little later, 2 furthest โ€” evict 2. Result: 6 hits (54.5%, or 85.7% ignoring the three compulsory misses). FIFO: evicts 0 just because it was first inโ€ฆ and the very next access is 0. Result: 4 hits (36.4%). Same stream, same cache โ€” the decision is everything.

The first three misses are unavoidable โ€” compulsory (cold-start) misses against an empty cache.

Aside: Types Of Cache Misses โ€” The Three Cโ€™s

Architects sort misses into compulsory (first-ever reference, empty cache), capacity (the cache ran out of room and evicted), and conflict (hardware set-associativity limits where an item may live). The third kind never afflicts the OS page cache: it is fully associative โ€” any page may occupy any frame.

Tip: Comparing Against Optimal Is Useful

โ€œMy policy hits 80%โ€ means little alone. โ€œOptimal hits 82%โ€ turns it into a result: youโ€™re near the ceiling, and further tuning has little left to win. Knowing the ideal tells you both how much improvement remains and when to stop.

22.3 A Simple Policy: FIFO

Early systems dodged the complexity: first-in, first-out. Pages join a queue on arrival; evict the oldest. Gloriously simple โ€” and blind. Flip the chip in the widget above and watch FIFO throw out page 0 because it arrived first, one access before page 0 is needed again: 4 hits to optimalโ€™s 6. FIFO simply cannot perceive that some pages are important.

Aside: Beladyโ€™s Anomaly

Bigger cache, better hit rate โ€” surely? Belady, Nelson, and Shedler found a FIFO stream where a FOUR-page cache loses to a three-page one. Count it yourself:

Belady's anomaly: FIFO on 1,2,3,4,1,2,5,1,2,3,4,5 โ€” run it at cache size 3, then size 4, and count the hits
cache size:
AccessHit/Miss?EvictResulting Cache State
โ–ถ step through the trace, or run it all

FIFO: 3 hits with 3 frames, TWO with 4 โ€” a bigger cache made it worse (to the chagrin of Belady's co-authors, the anomaly bears only his name). Flip to LRU and the anomaly vanishes: 2 hits then 4, never worse โ€” LRU's stack property guarantees a size-N+1 cache always contains the size-N cache's contents.

The cure is structural: LRU (next sectionโ€™s star) has the stack property โ€” a cache of size N+1 always contains the size-N cache โ€” so more memory can never hurt it. FIFO and Random obey no such discipline, and Beladyโ€™s anomaly is the price.

Check yourself

1.T_M = 100ns, T_D = 10ms. Compute AMAT at a 90% hit rate โ€” and explain the lesson lurking in the answer.

2.Belady's optimal policy: what's the rule, and why is it both perfect and useless as a real policy?

3.On the canonical stream, the first three accesses (0, 1, 2) miss under EVERY policy. Why, and what are the Three C's these belong to?

4.On the same stream, FIFO manages 4 hits to optimal's 6. What's FIFO's structural blindness?

5.Belady's anomaly, and why LRU is immune:

5 questions