Demand Paging
Lecture Notes for CS 140
Winter 2013
John Ousterhout
- Readings for this topic from Operating Systems: Principles and Practice:
Chapter 9.
- Demand paging: not all of a process's virtual
address space needs to be loaded in main memory at any
given time. Each page can be either:
- In memory (physical page frame)
- On disk (backing store)
Page Faults
- What happens when a process references a page that is
in the backing store?
- For pages in the backing store, clear the present
bit in the page table entries.
- If present is not set, then a reference to the page
causes a trap to the operating system.
- These traps are called page faults.
- To handle a page fault, the operating system
- Finds a free page frame in memory
- Reads the page in from backing store to the page frame
- Updates the page table entry, setting present
- Resumes execution of the thread
- How does the OS figure out which page generated the fault?
- x86: hardware saves the virtual address that caused the fault
(CR2 register)
- On earlier machines OS got only address of faulting instruction,
must simulate the instruction and try every address to find the
one that generated the fault
- Restarting process execution after a page fault is tricky, since
the fault may have occurred in the middle of an instruction.
- If instructions are idempotent, just restart the
faulting instruction (hardware saves instruction address
during page fault).
- Non-idempotent instructions are more difficult to restart:
- Without hardware support it may be impossible to resume
a process safely after a page fault. Hardware must keep
track of side effects:
- Undo all side effects during a page fault?
- Save info about side effects, use it to restart
instruction "in the middle"
Page Fetching
- Once the basic page fault mechanism is working, the OS has
two scheduling decisions to make:
- Page fetching: when to bring pages into memory.
- Page replacement: which pages to throw out of memory.
- Overall goal: make physical memory look larger than it is.
- Locality: most programs spend most of their time
using a small fraction of their code and data.
- Keep in memory the information that is being used.
- Keep unused information on disk in paging file
(also called backing store, or swap space)
- Ideally: paging produces a memory system with the performance
of main memory and the cost/capacity of disk!
- Most modern OSes use demand fetching:
- Start process with no pages loaded, don't load a page into
memory until it is referenced.
- The pages for a process divide into three groups:
- Read-only code pages: read from the executable file
when needed.
- Initialized data pages: on first access, read from
executable file. Once loaded, save to the
paging file since contents may have changed.
- Uninitialized data pages: on first access, just clear
memory to all zeros. When paging out, save to the
paging file.
- Prefetching: try to predict when pages will be needed
and load them ahead of time to avoid page faults.
- Requires predicting the future, so hard to do.
- One approach: when taking a page fault, read many
pages instead of just one (wins if program accesses
memory sequentially).
Page Replacement
- Once all of memory is in use, will need to throw out one
page each time there is a page fault.
- Random: pick any page at random (works surprisingly well!)
- FIFO: throw out the page that has been in memory longest.
- MIN: The optimal algorithm requires us to predict the
future.
- Least Recently Used (LRU): use the past to predict the
future.
- Implementing LRU: need hardware support to keep track of
which pages have been used recently.
- Perfect LRU?
- Keep a hardware register for each page, store system clock
into that register on each memory reference.
- To choose page for placement, scan through all pages
to find the one with the oldest clock.
- Hardware costs prohibitive in the early days of
paging; also, expensive to scan all pages during
replacement.
- No machines have actually implemented this.
- Current computers settle for an approximation that is efficient.
Just find an old page, not necessarily the oldest.
- Clock algorithm (also called second chance algorithm):
keep reference bit for each page frame,
hardware sets the reference bit whenever a page is read or written
To choose page for placement:
- Cycle through pages in order (circularly).
- If the next page has been referenced, then don't replace it;
just clear the reference bit and continue to the next page.
- If the page has not been referenced since the last time we
checked it, then replace that page.
- Dirty bit: one bit for each page frame, set by
hardware whenever the page is modified. If a dirty page
is replaced, it must be written to disk before its
page frame is reused.
- The clock algorithm typically gives additional preference
to dirty pages. For example, if the reference bit for a
page is clear, but the dirty bit is set, don't replace this
page now, but clear the dirty bit and start writing the
page to disk.
- Free page pool: many systems keep a small list of clean pages
that are available immediately for replacement.
- During replacement, take the page that has been in the
free pool the longest, then run the replacement algorithm
to add a new page to the free pool.
- Pages in the free pool have their present bit off,
so any references to those pages cause a page fault
- If a page fault occurs for a page in the free pool,
remove it from the free pool and put it back in service;
much faster than reading from disk.
- Provides an extra opportunity for recovery if we
make a poor page replacement decision.
- How to implement page replacement when there are multiple
processes running in the system?
- Global replacement: all pages from all processes
are lumped into a single replacement pool. Each process
competes with all the other processes for page frames.
- Per-process replacement: each process has a
separate pool of pages. A page fault in one process can
only replace one of that process's frames. This relieves
interference from other processes.
- Unfortunately, per-process replacement creates a new
scheduling dilemma: how many page frames to allocate to each
process? If this decision is made incorrectly, it can result
in inefficient memory usage.
- Most systems use global replacement.