Β§22.7–22.12Implementing Historical Algorithms … Summary

Part I OSTEP pp. 253–257 Β· ~6 min read

  • use bit
  • clock algorithm
  • demand paging
  • prefetching
  • clustering
  • thrashing
  • working set
  • admission control

LRU wins on quality β€” now the bill. To implement it perfectly, some structure must move the accessed page to the MRU position on every single memory reference. Even with hardware stamping per-page time fields, eviction means scanning them all: a 4GB machine with 4KB pages has a million pages to examine. Which begs the question: do we need the absolute oldest page β€” or will close-enough do?

The Crux: How To Implement An LRU Replacement Policy

Given that it will be expensive to implement perfect LRU, can we approximate it in some way, and still obtain the desired behavior?

22.8 Approximating LRU

Yes β€” and it’s what modern systems do. The hardware contribution is one use bit per page (a.k.a. the reference bit; first appearing in the Atlas): set to 1 by hardware whenever the page is referenced, cleared only by the OS. From that single bit, Corbató’s clock algorithm conjures an LRU approximation:

The clock algorithm: a hand, a circle of pages, and one bit each
Au=1Bu=1Cu=0Du=1Eu=0 Β· dirtyFu=1Gu=1Hu=0

1A miss arrives; the cache is full

Eight resident pages, arranged (conceptually) in a circle. Hardware has been setting use bits to 1 on every reference β€” hardware sets, only the OS clears. The hand starts wherever it last stopped; a victim must be found.

step 1 / 6

(The clock is one arrangement among many: any scheme that periodically clears use bits and prefers use=0 victims approximates LRU. The clock’s charm is never rescanning all of memory.) How good is the approximation? Run it against the field:

Figure 22.9, computed live: the 80-20 workload with the clock approximation joining the field
0%20%40%60%80%100%020406080100Cache Size (Blocks)Hit RateOPTLRUFIFORANDCLOCK

computed live: 10,000 refs over 100 pages (80/20 hot-cold), seeded β€” not a scanned figure

Clock lands where an approximation should: below true LRU (its information is one bit, not a full recency order), but comfortably above the history-blind policies. For one use bit and a lazy hand, that's a bargain.

22.9 Considering Dirty Pages

The StepThrough’s last frame already gave it away: eviction cost is not uniform. A dirty (modified) page must be written back to disk before its frame is free; a clean page’s eviction is free β€” the disk copy is already current. The hardware dirty bit (set on any write) feeds this into the policy: scan for unused-and-clean first, unused-and-dirty second.

22.10 Other VM Policies

Replacement isn’t the only decision. Page selection (Denning’s term) governs when pages come in: for most pages, demand paging β€” load on first access; plus prefetching when the odds are good (code page P just arrived β†’ P+1 is likely next). And on the way out, clustering : gather pending writes and issue them as one large disk write β€” disks do one big write far more efficiently than many small ones.

22.11 Thrashing

What if demand simply exceeds physical memory β€” every policy’s nightmare? The system pages constantly and accomplishes little: thrashing . The classic answer is admission control : refuse to run some processes, hoping the survivors’ working sets β€” the pages they actively use β€” fit in memory. Better to do less work well than everything at once poorly (a lesson with applications beyond paging, sadly). Some modern systems are blunter: versions of Linux run an out-of-memory killer that picks a memory-intensive process and terminates it β€” effective, if unsubtle, and occasionally it shoots the X server and takes the whole display down with it.

22.12 Summary

The full policy toolkit: optimal as the yardstick; FIFO and Random as cheap baselines; LRU as locality’s champion; clock and its dirty-bit variant as the affordable approximations modern systems actually run. Newer algorithms add scan resistance (ARC, among others) to dodge LRU’s looping-sequential worst case β€” the evolution continues. And a closing dose of humility: as the memory/disk gap has widened, paging of any kind has become so costly that the best fix for a thrashing system is often the intellectually unsatisfying one β€” buy more memory.

Homework: paging-policy.py

Trace hits and misses by hand under FIFO, LRU, and OPT (seeds 0/1/2); craft WORST-CASE streams for FIFO, LRU, and MRU with a 5-page cache and find how much bigger the cache must grow to approach OPT; then instrument a real program with valgrind (β€”tool=lackey β€”trace-mem=yes), mask addresses down to VPNs, and plot your application’s working set as cache size grows. Get it at ostep-homework.

Check yourself

1.Why is PERFECT LRU too expensive to run, even with hardware help?

2.Walk one clock-algorithm eviction: hand at a page with use=1, next page use=1, next use=0.

3.Why do VM systems prefer evicting CLEAN pages over dirty ones, and what supports the preference?

4.Beyond replacement, the VM system decides WHEN pages come in and HOW they go out. Name the policies.

5.Memory demand exceeds physical memory and the system pages constantly β€” thrashing. Compare the classic and the modern responses.

5 questions