Page replacement algorithm

From Wikipedia, the free encyclopedia

In a computer operating system which utilises paging for virtual memory memory management, page replacement algorithms decide what pages to page out (swap out) when a page needs to be allocated. This happens when a page fault occurs and a free page cannot be used to satisfy the allocation, either because there are none, or because the number of free pages is lower than some threshold.

When the page that was selected for replacement and paged out is referenced again it has to be paged in, and this usually involves waiting for I/O completion. This determines the quality of the page replacement algorithm: the less time wasted by waiting for page-ins, the better the algorithm. A page replacement algorithm tries, by looking at the limited information about accesses to the pages provided by hardware, to guess what pages should be replaced in order to minimize the total number of page misses, while balancing this with the costs (primary storage and processor time) of the algorithm itself.

Contents

[edit] History

Page replacement algorithms were a hot topic of research and debate in the 1960s and 1970s. That mostly ended with the development of sophisticated LRU approximations and working set algorithms. Since then, however, some basic assumptions made by the traditional page replacement algorithms were to some degree invalidated, resulting in a revival of research in that area. In particular, the following trends in the behavior of underlying hardware and user-level software affected performance of page replacement algorithms:

  • Size of primary storage increased by multiple orders of magnitude. With several gigabytes of primary memory, algorithms that require a periodic check of each and every memory frame are becoming less and less practical.
  • Memory hierarchies grew taller. The cost of a CPU cache miss is far more expensive. This exacerbates the previous problem.

Also, requirements for page replacement algorithms have changed due to differences in operating system kernel architectures. In particular, most modern OS kernels have unified virtual memory and file system caches, requiring the page replacement algorithm to select a page from among the pages of both user program virtual address spaces and cached files. The latter pages have specific properties. For example, they can be locked, or can have write ordering requirements imposed by journaling. Moreover, as the goal of page replacement is to minimize total time wasted by waiting for memory, it has to take into account memory requirements imposed by other kernel sub-systems that allocate memory. As a result, in modern kernels (Linux, FreeBSD, and Solaris) page replacement tends to work at the level of a general purpose kernel memory allocator, rather than at the higher level of a virtual memory subsystem proper.

[edit] Local vs. global replacement

Replacement algorithms can be local or global. When a process incurs a page fault, a local page replacement algorithm selects for replacement some page that belongs to that same process (or a group of processes sharing a memory partition). A global replacement algorithm is free to select any page in memory.

Local page replacement assumes some form of memory partitioning that determines how many pages are to be assigned to a given process of a group of processes. Most popular forms of partitioning are fixed partitioning and balanced set algorithms based on the working set model. The advantage of local page replacement is its scalability: each process can handle its page faults independently without contending for some shared global data structure.

[edit] Precleaning

Most textbook replacement algorithms simply return target page as their result. This means that if target page is dirty (that is, contains data that have to be written to the stable storage before page can be reclaimed), I/O has to be initiated to send that page to the stable storage (to clean the page). In the early days of virtual memory, time wasted on cleaning wasn't of much concern, because virtual memory was first implemented on systems with full duplex channels to the stable storage, and cleaning was customarily overlapped with pagein. Contemporary commodity hardware, on the other hand, doesn't support full duplex transfers, and cleaning of target pages becomes an issue.

To deal with this various precleaning policies are implemented. Precleaning is mechanism that starts I/O on dirty pages that are (likely) to be replaced soon. The idea is that by the time the precleaned page is actually selected for the replacement I/O will finish and page will be clean. Precleaning assumes that it is possible to identify pages that will be replaced next. Precleaning that is too eager can waste I/O bandwidth by writing pages that manage to get re-dirtied before being selected for replacement.

[edit] The theoretically optimal page replacement algorithm

The theoretically optimal page replacement algorithm (also known as OPT or clairvoyant replacement algorithm) is an algorithm which works as follows: when a page needs to be swapped in, the operating system swaps out the page whose next use will occur farthest in the future. A page that is not going to be used until 6 million microseconds pass will be swapped out over a page which is going to be used after 4 thousand microseconds.

However, this algorithm cannot be implemented in the general purpose operating system, simply because it is impossible for the operating system to compute how long it is before a page is going to be used, except when all software that will run on a system is either known beforehand and is amenable to the static analysis of its memory reference patterns, or only a class of applications allowing run-time analysis is allowed. In spite of this, there exist algorithms which can offer near-optimal performance — on the first run of a program, the operating system keeps track of all the pages which it references, and by using this data, it decides what pages to swap in and out on the second run. This algorithm can offer near-optimal performance, but not on the first run of a program, and only if the program's memory reference pattern is relatively consistent across runs.

Analysis of the paging problem has also been done in the field of online algorithms. Efficiency of randomized online algorithms for the paging problem are measured using amortized analysis.

[edit] Not recently used

The not recently used (NRU) page replacement algorithm is an algorithm which favours keeping pages which have been recently used. This algorithm works on the following principle: when a page is referenced, a referenced bit will be set for that page, marking it as referenced. Similarly, when a page is modified (written to), a modified bit will be set. The setting of the bits is usually done by the hardware, although it is possible to do so on the software level as well.

At a certain fixedtime interval, the clock interrupt triggers and clears the referenced bit of all the pages, so only pages referenced within the current clock interval are marked with a referenced bit. When a page needs to be replaced, the operating system divides the pages into four classes:

  • Class 0: not referenced, not modified
  • Class 1: not referenced, modified
  • Class 2: referenced, not modified
  • Class 3: referenced, modified

Although it does not seem possible for a page to be not referenced yet modified, this happens when a category 3 page has its referenced bit cleared by the clock interrupt. The NRU algorithm simply picks a random page from the lowest category for removal. Note that this algorithm implies that a referenced page is more important than a modified page.

[edit] First-in, first-out

The first-in, first-out (FIFO) page replacement algorithm is another low-overhead algorithm which requires little bookkeeping on the part of the operating system. The idea is obvious from the name - the operating system keeps track of all the pages in memory in a queue, with the most recent arrival at the back, and the earliest arrival in front. When a page needs to be replaced, the page at the front of the queue is selected, as it will be the oldest page. While FIFO is cheap and intuitive, it performs relatively badly in practical application. Thus, it is rarely used in its unmodified form. This algorithm experiences Belady's anomaly.

FIFO page replacement algorithm is used by the VAX/VMS operating system.[1]

[edit] Second-chance

A modified form of the FIFO page replacement algorithm, known as the second chance page replacement algorithm, fares relatively better than FIFO at little cost for the improvement. It works by looking at the front of the queue as FIFO does, but instead of immediately swapping (usage of this term is technically wrong; instead one should use the term paging out) out that page, it checks to see if its referenced bit is set. If it is not set, the page is swapped out. Otherwise, the referenced bit is cleared, and the page is inserted at the back of the queue, as if it were a new page, and this process is repeated. This can also be thought of as a circular queue. If all the pages have their referenced bit set, on the second encounter of the first page in the list, that page will be swapped out, as it now has its referenced bit cleared.

Essentially, what second-chance does is, as its name suggests, giving every page a "second-chance" - an old page which has been referenced is probably in use, and should not be swapped out over a new page which has not been referenced.

[edit] Least recently used

The least recently used page (LRU) replacement algorithm, though similar in name to NRU, differs in the fact that LRU keeps track of page usage over a short period of time, while NRU just looks at the usage in the last clock interval. LRU works on the idea that the pages which have been most heavily used in the past few instructions will be used heavily in the next few instructions too. While LRU can provide near-optimal performance in theory, it is rather expensive to implement in practice. There are a few implementation methods for this algorithm which try to reduce the cost yet keep as much of the performance as possible.

The most expensive method is the linked list method, whereby there is a linked list containing all the pages in memory. At the back of this list is the least recently used page, and at the front is the most recently used page. The cost of this implementation lies in the fact that items in the list will have to be moved about every memory reference, which is a very time-consuming process.

Another way, which requires hardware support is as follows: suppose the hardware has a 64-bit counter which is incremented at every instruction. Whenever a page is accessed, it gains a value equal to the counter at the time of page access. Whenever a page needs to be replaced, the operating system simply picks out the page which has the lowest counter, and swaps it out. This is not feasible in present hardware as there exists no such hardware counters.

Because of these implementation costs, one may consider algorithms, such as those which follow, which are similar to LRU, but which offer cheaper implementations.

One important advantage of LRU algorithm is that it is amenable to the full statistical analysis. It has been proved, for example, that LRU can never result in more than N-times more page faults than OPT algorithm, where N is proportional to the number of pages in the managed pool.

On the other hand, LRU's weakness is that its performance tends to degenerate under many quite common reference patterns. For example, if there are N pages in the LRU pool, then application doing loop over array of N + 1 pages will cause page fault on each and every access. As loops over large arrays are extremely common a lot of effort was put into modifying LRU to work better in such situations. Many of proposed LRU modifications try to detect looping reference pattern and to switch into suitable replacement algorithm, like Most Recently Used (MRU).

[edit] Variants on LRU

  1. LRU-K improves greatly on LRU with regard to locality in time. It's also known as LRU-2, for the case that K=2. LRU-1 (i.e. K=1) is the same as normal LRU.
  1. The ARC[2] algorithm extends LRU by maintaining a history of recently evicted pages and uses this to change preference to recent or frequent access. It is particularly resistant to sequential scans.

A comparison of ARC with other algorithms (LRU,MQ,2Q,LRU-2,LRFU,LIRS) can be found in Megiddo & Modha[3]

[edit] Random

Random replacement algorithm replaces random page in memory. However silly that may sound, this algorithm is useful in certain situations. Usually it fares better than FIFO, and for looping memory references it is better than LRU, although generally LRU performs better in practice. OS/390 uses global LRU approximation and falls back to random replacement when LRU performance degenerates, and the Intel i860 processor used a random replacement policy (Rhodehamel 1989).

[edit] Not frequently used

The not frequently used (NFU) page replacement algorithm also requires a counter, but every page has one counter of its own, which is initially zero. At each clock interval, all pages which have been referenced within that interval will have their counter incremented by 1. In effect, the counters keep track of how frequently a page has been used. Thus, the page with the lowest counter can be swapped out when necessary.

The main problem with NFU is that it keeps track of the frequency of use without regard to the time span of use. Thus, in a multi-pass compiler, pages which were heavily used during the first pass, but are not needed in the second pass will be favoured over pages which are comparably lightly used in the second pass, as they have higher frequency counters. This results in poor performance. Other common scenarios exist where NFU will perform similarly, such as an OS boot-up. Thankfully, a similar and better algorithm exists, and its description follows.

[edit] Aging

The aging algorithm is a descendant of the NFU algorithm, with modifications to make it aware of the time span of use. Instead of just incrementing the counters of pages referenced, putting equal emphasis on page references regardless of the time, the reference counter on a page is first shifted right (divided by 2), before adding the referenced bit to the left of that binary number. For instance, if a page has referenced bits 1,0,0,1,1,0 in the past 6 clock ticks, its referenced counter will look like this: 10000000, 01000000, 00100000, 10010000, 11001000, 01100100. As you can see, page references closer to the present have more impact than page references long ago. This ensures that pages referenced more recently, though less frequently referenced, will have higher priority over pages more frequently referenced in the past. Thus, when a page needs to be swapped out, the page with the lowest counter will be chosen.

Note that aging differs from LRU in the sense that aging can only keep track of the references in the latest 16/32 (depending on the bit size of the processor's integers) time intervals. Consequently, two pages may have referenced counters of 00000000, even though one page was referenced 9 intervals ago and the other 1000 intervals ago. Generally speaking, knowing the usage within the past 16 intervals is sufficient for making a good decision as to which page to swap out. Thus, aging can offer near-optimal performance for a moderate price.

[edit] References

  1. ^ Abraham Silberschatz, Peter Baer Galvin, Greg Gagne. Operating Systems Concepts. ?: Wiley 2005. p. 339.
  2. ^ Megiddo & Modha, ARC: A Self-tuning, low overhead replacement cache
  3. ^ Nimrod Megiddo & Dharmendra S. Modha, Outperforming LRU with an Adaptive Replacement Cache AlgorithmPDF (123 KiB), IEEE Computer Magazine, pp. 58-65, April 2004.

See Also:

  • Tanenbaum, Andrew S. Operating Systems: Design and Implementation (Second Edition). New Jersey: Prentice-Hall 1997.
In other languages