Demand Paging Optimization

Last time, we started to see that the cost of page faults can get pretty prohibitive, so we should consider a couple extra tricks to avoid them when possible!


Copy-on-Write


Suppose a child process is fork()ed from a parent; when is the first time the child will need its own copy of the parent's memory image?

Only when it makes some edit (i.e., some write operation) to memory!

The copy-on-write optimization will, for a child process, use the parent's memory image as though it was it's own until it needs to write to its image, at which point a new page is allocated for it.

Consider two processes such that \(P_2\) is the parent of \(P_1\) and they share three pages \(A, B, C\) after the fork() operation.

This would give us the image:

Now, after \(P_1\) modifies Page C, we would only now provide it with a copy, rather than copying all of \(A, B, and C\) (and possibly more pages from \(P_2\) in the backing store!) from the fork:


vfork


Hey! Let's learn about a tool you might've wanted to use in your last homework!

If we want to implement copy-on-write, we should probably be able to specify if and when we'd like that to happen with OS support:

The vfork() syscall has the same effect as fork() except that the behavior is undefined if the child makes any modifications to data; it is typically paired with exec() family of system calls since it will not consume the time and memory copying any pages from the parent unnecessarily.



Page Replacement

A reasonable question to ask with demand paging is: "What if there is no free frame?"

How should the pager act if there is no free frame in physical memory for a demanded page?

Choose a victim frame by some algorithm to swap out for the demanded page.

This would look like the following:

Of course, we're always looking for opportunities to optimize any page swapping procedures... for example:

Is there a scenario in which step #1 above would be unnecessary? If so, how would you detect it?

Yes! In the case where the victim frame has not been modified since being loaded from the backing store, it need not be written back. This can be detected by maintaining a dirty-bit on each frame in the page-table, such that the swap-out only occurs if the dirty-bit has been set to indicate that the page has been written to.


Page Replacement Algorithms


More importantly, however, we must determine: in the case where there is no free frame, who is to be the victim?

Page Replacement Algorithms choose a victim frame from among those that are currently occupied by a process to satisfy the demand for a page.

Page replacement algorithms are typically tested via a reference string indicating an order of pages requested, and a finite number of available frames.


First-in First-out (FIFO) Page Replacement

Per usual, let's start by looking at the easy, but dumb, solution to a problem and then show in a flourish how we might do better...

The First-in First-out (FIFO) Page Replacement Algorithm uses a queue for replacement, inserting new pages at the tail and dequeueing old pages at the head.

Determine the number of page faults experienced by the FIFO replacement algorithm on the following reference string with 3 frames: $$7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1$$

One would expect that as the number of frames that are available increase, the number of page faults should decrease... but do they?

Determine the number of page faults experienced by the FIFO replacement algorithm on the following reference string with 4 frames: $$1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5$$

Belady's Anomaly occurs for some page replacement algorithms such that the page fault rate may increase with an added number of available frames!

FIFO replacement is one such algorithm susceptible to Belady's Anomaly!

So, can we devise some approaches that are not?

Let's consider the best case scenario: what would be the ideal replacement algorithm, even if we might have trouble implementing it in practice?

Replace the page that is going to be used most distantly in the future!


Optimal (OPT) Page Replacement

The Optimal Page Replacement (OPT) Algorithm replaces the page that will not be used for the longest period of time.

OPT has some very nice properties: (1) it provably leads to the optimally few number of page faults and (2) it is *not* susceptible to Belady's Anomaly.

Determine the number of page faults experienced by the OPT replacement algorithm on the same reference string with 3 frames: $$7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1$$

What's the problem with OPT?

In practice, how would we be able to tractably know when any given page is next demanded?!

For this reason, we must look elsewhere... in particular:

If we cannot look into the future (darn), where might we look to avoid Belady's Anomaly and also reduce our number of page faults?

The past, duh! We can consider the victim to be the one that we used least recently in the past!


Least-Recently Used (LRU) Page Replacement

The Least Recently Used (LRU) Algorithm replaces the page that has not been used for the longest time.

Determine the number of page faults experienced by the LRU replacement algorithm on the same reference string with 3 frames: $$7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1$$

LRU is considered a satisfactory approach to page replacement and also avoids Belady's Anomaly.

The question, however, is how to implement it -- what mechanism(s) would be appropriate for easily determining which page is the least recently used?

There are two primary approaches:

  • Counters: keep "timestamp" counters on each page-table entry that are incremented with every memory reference, and reset when a new page is swapped in. The largest counter is therefore the least recently used.

  • Stacks: organize the pages in a doubly linked list with head and tail, but treated as a stack such that, whenever a page is referenced, it is put on the top of the stack (Most RU), and those that are LRU drift to the bottom (LRU). As such, the bottom / tail serves as a constant time reference to the page that should be replaced next.



  PDF / Print