Working Set缓存算法(转)

为了加深对缓存算法的理解,特转此篇,又由于本文内容过多,故不做翻译,原文地址Working Set页面置换算法

In the purest form of paging, processes are started up with none of their pages in memory. As soon as the CPU tries to fetch the first instruction, it gets a page fault, causing the operating system to bring in the page containing the first instruction. Other page faults for global variables and the stack usually follow quickly. After a while, the process has most of the pages it needs and settles down to run with relatively few page faults. This strategy is called demand paging because pages are loaded only on demand, not in advance.

Of course, it is easy enough to write a test program that systematically reads all the pages in a large address space, causing so many page faults that there is not enough memory to hold them all. Fortunately, most processes do not work this way. They exhibit a locality of reference, meaning that during any phase of execution, the process references only a relatively small fraction of its pages. Each pass of a multipass compiler, for example, references only a fraction of all the pages, and a different fraction at that.

The set of pages that a process is currently using is called its working set (Denning, 1968a; Denning, 1980). If the entire working set is in memory, the process will run without causing many faults until it moves into another execution phase (e.g., the next pass of the compiler). If the available memory is too small to hold the entire working set, the process will cause many page faults and run slowly since executing an instruction takes a few nanoseconds and reading in a page from the disk typically takes 10 milliseconds. At a rate of one or two instructions per 10 milliseconds, it will take ages to finish. A program causing page faults every few instructions is said to be thrashing (Denning, 1968b).

In a multiprogramming system, processes are frequently moved to disk (i.e., all their pages are removed from memory) to let other processes have a turn at the CPU. The question arises of what to do when a process is brought back in again. Technically, nothing need be done. The process will just cause page faults until its working set has been loaded. The problem is that having 20, 100, or even 1000 page faults every time a process is loaded is slow, and it also wastes considerable CPU time, since it takes the operating system a few milliseconds of CPU time to process a page fault.

Therefore, many paging systems try to keep track of each process‘ working set and make sure that it is in memory before letting the process run. This approach is called the working set model (Denning, 1970). It is designed to greatly reduce the page fault rate. Loading the pages before letting processes run is also called prepaging. Note that the working set changes over time.

It has been long known that most programs do not reference their address space uniformly, but that the references tend to cluster on a small number of pages. A memory reference may fetch an instruction, it may fetch data, or it may store data. At any instant of time, t, there exists a set consisting of all the pages used by the most recent memory references. This set, w(kt), is the working set. Because the k= 1 most recent references must have used all the pages used by the k > 1 most recent references, and possibly others, w(kt) is a monotonically nondecreasing function of k. The limit of w(kt) as becomes large is finite because a program cannot reference more pages than its address space contains, and few programs will use every single page. Figure 4-5 depicts the size of the working set as a function of k.

Figure 4-5. The working set is the set of pages used by the k most recent memory references. The function w(k, t) is the size of the working set at time t.

The fact that most programs randomly access a small number of pages, but that this set changes slowly in time explains the initial rapid rise of the curve and then the slow rise for large k. For example, a program that is executing a loop occupying two pages using data on four pages, may reference all six pages every 1000 instructions, but the most recent reference to some other page may be a million instructions earlier, during the initialization phase. Due to this asymptotic behavior, the contents of the working set is not sensitive to the value of chosen. To put it differently, there exists a wide range of kvalues for which the working set is unchanged. Because the working set varies slowly with time, it is possible to make a reasonable guess as to which pages will be needed when the program is restarted on the basis of its working set when it was last stopped. Prepaging consists of loading these pages before the process is allowed to run again.

To implement the working set model, it is necessary for the operating system to keep track of which pages are in the working set. Having this information also immediately leads to a possible page replacement algorithm: when a page fault occurs, find a page not in the working set and evict it. To implement such an algorithm, we need a precise way of determining which pages are in the working set and which are not at any given moment in time.

As we mentioned above, the working set is the set of pages used in the most recent memory references (some authors use the most recent page references, but the choice is arbitrary). To implement any working set algorithm, some value of must be chosen in advance. Once some value has been selected, after every memory reference, the set of pages used by the previous memory references is uniquely determined.

Of course, having an operational definition of the working set does not mean that there is an efficient way to monitor it in real time, during program execution. One could imagine a shift register of length k, with every memory reference shifting the register left one position and inserting the most recently referenced page number on the right. The set of all page numbers in the shift register would be the working set. In theory, at a page fault, the contents of the shift register could be read out and sorted. Duplicate pages could then be removed. The result would be the working set. However, maintaining the shift register and processing it at a page fault would both be prohibitively expensive, so this technique is never used.

Instead, various approximations are used. One commonly used approximation is to drop the idea of counting back memory references and use execution time instead. For example, instead of defining the working set as those pages used during the previous 10 million memory references, we can define it as the set of pages used during the past 100 msec of execution time. In practice, such a definition is just as good and much easier to use. Note that for each process, only its own execution time counts. Thus if a process starts running at time and has had 40 msec of CPU time at real time + 100 msec, for working set purposes, its time is 40 msec. The amount of CPU time a process has actually used has since it started is often called its current virtual time. With this approximation, the working set of a process is the set of pages it has referenced during the past t seconds of virtual time.

Now let us look at a page replacement algorithm based on the working set. The basic idea is to find a page that is not in the working set and evict it. In Fig. 4-6 we see a portion of a page table for some machine. Because only pages that are in memory are considered as candidates for eviction, pages that are absent from memory are ignored by this algorithm. Each entry contains (at least) two items of information: the approximate time the page was last used and the (Referenced) bit. The empty white rectangle symbolizes the other fields not needed for this algorithm, such as the page frame number, the protection bits, and the (Modified) bit.

Figure 4-6. The working set algorithm.

The algorithm works as follows. The hardware is assumed to set the and bits, as we have discussed before. Similarly, a periodic clock interrupt is assumed to cause software to run that clears theReferenced bit on every clock tick. On every page fault, the page table is scanned to look for a suitable page to evict.

As each entry is processed, the bit is examined. If it is 1, the current virtual time is written into the Time of last use field in the page table, indicating that the page was in use at the time the fault occurred. Since the page has been referenced during the current clock tick, it is clearly in the working set and is not a candidate for removal (t is assumed to span multiple clock ticks).

If is 0, the page has not been referenced during the current clock tick and may be a candidate for removal. To see whether or not it should be removed, its age, that is, the current virtual time minus its Time of last use is computed and compared to t. If the age is greater than t, the page is no longer in the working set. It is reclaimed and the new page loaded here. The scan continues updating the remaining entries, however.

However, if is 0 but the age is less than or equal to t, the page is still in the working set. The page is temporarily spared, but the page with the greatest age (smallest value of Time of last use) is noted. If the entire table is scanned without finding a candidate to evict, that means that all pages are in the working set. In that case, if one or more pages with = 0 were found, the one with the greatest age is evicted. In the worst case, all pages have been referenced during the current clock tick (and thus all have = 1), so one is chosen at random for removal, preferably a clean page, if one exists.

时间: 2024-10-05 23:26:58

Working Set缓存算法(转)的相关文章

常见的缓存算法设计策略

对于缓存,大家应该都不会感到陌生,但是关于缓存算法有哪些,大家可能不会太清楚,这里我大概介绍下. 缓存的设计目的就是为了我们访问方便,减少访问时间,大体上有这四种策略: 一:基于时间的策略.当缓存未满的时候,一直向缓存区添加,当缓存区满的时候,再有数据进来,就需要将以访问过的数据清除掉. 清除的就是那些访问时间久的数据.说白了就是访问时间距离现在越远的将首先被淘汰. 二:基于频率的策略.当缓冲区满的时候,按照访问频率将数据进行排序,将那些访问频率较少的数据淘汰掉. 三:基于时间和频率的策略.当缓

缓存算法合辑

缓存算法有很多种策略,具体可以参见https://en.wikipedia.org/wiki/Cache_replacement_policies.其中最常提到的就是LRU和LFU了. 1. LRU 问题描述: Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put. get(key) - G

本地应用缓存算法和缓存策略的介绍

特别声明:该文章是 本人在网上搜索到的一些资料,稍作整理而成的,还望大家不要误会,具体出自于那本人也已经忘记.还请大家不要误会!!!   通过设计良好的数据分块.预取.替换.更新等算法来提高对缓存内容的命中率和一致性. 1)数据分块      Memcached默认情况下采用了名为Slab Allocator的机制分配.管理内存.在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的.但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操

带你了解Android常见的内存缓存算法

带你了解Android常见的内存缓存算法 本片博客主要简介以下两个问题 介绍一下常见的内存缓存算法 怎样实现这些算法 大家应该对ImageLoader这个框架都不陌生吧,一个很强大的图片加载框架,虽然作者去年的时候已经停止维护了,但里面的许多东西还是值得我们去学习的.本篇博客讲解的内存缓存算法正是基于ImageLoader的实现基础之上的 常见的几种缓存算法 (1)LRU即Least RecentlyUsed,近期最少使用算法. 也就是当内存缓存达到设定的最大值时将内存缓存中近期最少使用的对象移

缓存算法之LRU与LFU

1 LRU算法 1.1 前言     目前尽量由于摩尔定律,但是在存储硬件始终存在着矛盾,例如在容量方面,内存<外存:而在硬件成本与访问效率方面,内存>外存,并且这种区别是不在同一数量级别的差异.而目前互联网服务平台存在的特点:读多写少,数据规模巨大,长尾效应等等.正是由于场景需求与存储硬件之间的本身矛盾,缓存算法由此产生了.      一个服务平台其读取过程:总是优先去离CPU最近的地方内存中读取数据,当有限的空间读取命中为空时,则去外存的数据库或文件系统中读取.当有限的缓存空间里“人满为患

Memcached之缓存雪崩,缓存穿透,缓存预热,缓存算法(7)

缓存雪崩 缓存雪崩可能是因为数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机. 解决思路: 1,采用加锁计数,或者使用合理的队列数量来避免缓存失效时对数据库造成太大的压力.这种办法虽然能缓解数据库的压力,但是同时又降低了系统的吞吐量. 2,分析用户行为,尽量让失效时间点均匀分布.避免缓存雪崩的出现. 3,如果是因为某台缓存服务器宕机,可以考虑做主备,比如:redis主备,但是双缓存涉及到更新事务的问题,update可能读到脏

[转]缓存、缓存算法和缓存框架简介

以下内容转自:http://www.leexiang.com/cache-algorithm (转载请注明出处)-----------------------------------分割线---------------------------------------------- 引言 我们都听过 cache,当你问他们是什么是缓存的时候,他们会给你一个完美的答案,可是他们不知道缓存是怎么构建的,或者没有告诉你应该采用什么标准去选择缓存框架.在这边文章,我们会去讨论缓存,缓存算法,缓存框架以及哪

Memcached之缓存雪崩,缓存穿透,缓存预热,缓存算法

缓存雪崩 缓存雪崩可能是因为数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机. 解决思路: 1,采用加锁计数,或者使用合理的队列数量来避免缓存失效时对数据库造成太大的压力.这种办法虽然能缓解数据库的压力,但是同时又降低了系统的吞吐量. 2,分析用户行为,尽量让失效时间点均匀分布.避免缓存雪崩的出现. 3,如果是因为某台缓存服务器宕机,可以考虑做主备,比如:Redis主备,但是双缓存涉及到更新事务的问题,update可能读到脏

缓存、缓存算法和缓存框架

译者:lixiang 译文:http://www.zavakid.com/25 原文:http://www.jtraining.com/component/content/article/35-jtraining-blog/98.html 引言 我们都听过 cache,当你问他们是什么是缓存的时候,他们会给你一个完美的答案,可是他们不知道缓存是怎么构建的,或者没有告诉你应该采用什么标准去选择缓存框架.在这边文章,我们会去讨论缓存,缓存算法,缓存框架以及哪个缓存框架会更好. 面试 “缓存就是存贮数