hfut-OS常见页面置换算法整理
在地址映射过程中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断。当发生缺页中断时,如果操作系统内存中没有空闲页面,则操作系统必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。而用来选择淘汰哪一页的规则叫做页面置换算法。
如今已经有很多页面置换算法,但是不同页面置换算法的主要目标还是使页面置换频率最低(即缺页率最低)。
1. 最佳置换算法
基本思想:选择以后再也不用的页面;没有的话,选择以后最长时间不用的页面;
实现:无法实现,因为页面的访问顺序无法预知;
特点:无法实现,仅具有理论意义;
2. 先进先出置换算法(FIFO)
基本思想:基于程序的顺序执行特点选择到达内存最早的页面,予以淘汰;
实现:页面在内存中按时间排序;
特点:效果不佳(程序不是严格顺序执行);
3. 最近最久未使用置换算法(LRU)
基本思想:基于程序运行的局部性原理,选择最近以来最久未使用的页面,予以淘汰;
实现:移位寄存器,栈;
特点:调度性能教好;
4. 第二次机会算法
第二次机会算法的基本思想是与FIFO相同的,但是有所改进,避免把经常使用的页面置换出去。当选择置换页面时,依然和FIFO一样,选择最早置入内存的页面。但是二次机会法还设置了一个访问状态位。所以还要检查页面的的访问位。如果是0,就淘汰这页;如果访问位是1,就给它第二次机会,并选择下一个FIFO页面。当一个页面得到第二次机会时,它的访问位就清为0,它的到达时间就置为当前时间。如果该页在此期间被访问过,则访问位置为1。这样给了第二次机会的页面将不被淘汰,直至所有其他页面被淘汰过(或者也给了第二次机会)。因此,如果一个页面经常使用,它的访问位总保持为1,它就从来不会被淘汰出去。
第二次机会算法可视为一个环形队列。用一个指针指示哪一页是下面要淘汰的。当需要一个存储块时,指针就前进,直至找到访问位是0的页。随着指针的前进,把访问位就清为0。在最坏的情况下,所有的访问位都是1,指针要通过整个队列一周,每个页都给第二次机会。这时就退化成FIFO算法了。
5. 时钟算法
需要用到页表项当中的访问位,当一个页面被装入内存时,把该位初始化为0,然后如果这个页面被访问(读/写),则把该位置为1;把各个页面组织成环形链表(类似于钟表面),把指针指向最老的页面(最先进来);当发生一个缺页中断时,考察指针所指向的最老页面,若它的访问位为0,立即淘汰;若访问位为1,则把该位置为0,然后指针往下移动一格,如此下去,直至找到被淘汰的页面,然后把指针移动到它的下一格。
6. 改进型的时钟置换算法
简单的时钟置换算法仅考虑到一个页面最近是否被访问过。事实上,如果被淘汰的页面没有被修改过,就不需要执行I/O操作写回外存。只有被淘汰的页面被修改过时,才需要写回外存。因此,除了考虑一个页面最近有没有被访问过之外,操作系统还应考虑页面有没有被修改过。在其他条件都相同时,应优先淘汰没有修改过的页面,避免I/O操作。这就是改进型的时钟置换算法的思想。
修改位=0,表示页面没有被修改过;修改位=1,表示页面被修改过。为方便讨论,用(访问位,修改位)的形式表示各页面状态。如(1,1)表示一个页面近期被访问过,且被修改过。算法规则:将所有可能被置换的页面排成一个循环队列。
实例:
第一轮:从当前位置开始扫描到第一个(0, 0)的帧用于替换。本轮扫描不修改任何标志位。
第二轮:若第一轮扫描失败,则重新扫描,查找第一个(0, 1)的帧用于替换。本轮将所有扫描过的帧访问位设为0。
第三轮:若第二轮扫描失败,则重新扫描,查找第一个(0, 0)的帧用于替换。本轮扫描不修改任何标志位。
第四轮:若第三轮扫描失败,则重新扫描,查找第一个(0, 1)的帧用于替换。
由于第二轮已将所有帧的访问位设为0,因此经过第三轮、第四轮扫描一定会有一个帧被选中,因此改进型CLOCK置换算法选择一个淘汰页面最多会进行四轮扫描。
7. 最近未使用页面置换算法(NRU)算法
找到最久没有使用的页面置换出去,页面被访问时设置访问位为1,修改时设置修改位为1,为便于说明,用R位标识访问位,M位标识修改位。R位定期清0;
此算法可以把页面分四类:
置换方式:系统从类类编号最小的非空类随机挑选一个置换。
8. 最不常用算法
用一个软件模拟LRU,该算法将每个页面与一个软件计数器相关联。计数器的初值为0。每次时钟中断时,由操作系统扫描内存中所有的页面,将每个页面的R位(它是0或1)加到它的计数器上。这个计数器大体上跟踪了各个页面被访问的频繁程度。发生缺页中断时,则置换计数器值最小的页面。
NFU的缺点是它不从不忘记任何事,比如一个页面之前频繁被访问,导致这个它的计数器很大,但是后来它不被访问了,而它的计数器的值还是很大,所以它一直不会被置换出去。
9. 老化算法
老化算法是对NFU算法的修改,其修改包括两个部分,首先,在R位被加进之前将计数器右移一位,其次,将R位加到计数器最左端的位而不是最右端的位。
老化算法中的计数器只有有限位数,如果时钟滴答是20ms,8位一般是够用的。假如一个页面160ms没有被访问过,那么它很可能并不重要。
10. 工作集页面置换算法
相关定义:
算法过程:
过程:扫描所有的页面检查R位:
若(R == 1)则设置上次使用时间为当前实际时间,表示缺页中断时该页面正在被使用。
若(R == 0 且生存时间>τ)则移出这个页面,该页面在当前时钟滴答中未被访问,不在工作集中,用新的页面置换它。扫描会继续进行以更新剩余的表项。
若(R == 0 且生存时间≤τ)则记住最小时间。如果该页面R==0且生存时间小于或等于τ,则页面仍在工作集中。把页面临时保存下来,但是要记住生存时间最长(“上次使用时间”的最小值)。如果扫描完整个页表却没有找到合适的淘汰的页面,如果找到了一个或多个R == 0的页面,就淘汰生存时间最长的页面。
在最坏的情况下,在当前时钟滴答中,所有的页面都被访问过了,也就是所有的R都为1,因此就随机选择一个页面淘汰,如果有的话最好选一个干净页面。
工作集时钟页面置换算法
工作集时钟页面置换算法是在工作集和时钟算法的基础上改进的。
在工作集页面置换算法中中,当缺页中断发生后,需要扫描整个页表才能确定被淘汰的页面,因此基本工作集算法是比较费时的。
基于时钟算法,并且使用了工作集信息,被称为WSClock(工作集时钟)算法。由于它实现简单,性能较好,所以在实际工作中得到了广泛应用。与时钟算法一样,所需的数据结构是一个以页框为元素的循环表。
最初,该表为空,当装入第一个页面后,把它加到该表中。随着更多的页面加入,它们形成一个环。每个表项包含来自基本工作集算法的上次使用时间,以及R位和M位。
与时钟算法一样,每次缺页中断时,首先检查指针指向的页面。如果R位是1,该页面在当前时钟滴答中就被使用过,那么该页面就不适合被淘汰。然后把该页面的R位置为0,指针指向下一个页面,并重复该算法。
如果R位是0,查看生存时间,如果生存时间大于τ并且该页面是干净的,它就不在工作集中,而且在磁盘上它有一个有效的副本。申请此页框,并把新页面放在其中。如果该页面已经被修改过,就不立即申请此页框,为了避免由于调度写磁盘操作引起的进程切换,指针继续向前走,算法继续对下一个页面进行操作,有可能存在一个旧的而且干净的页面可以立即使用。
原则上,所有的页面都有可能因为磁盘I/O在某个时钟周期被调度,为了降低磁盘阻塞,需要设置一个限制,即最大只允许写回n个页面。一旦达到该限制,就不允许调度新的写操作。
指针经过一圈返回它的起点,有两种情况:
算法对比:
算法 |
优缺点 |
最优算法 |
不可实现,但可以用作基准 |
NRU(最近未使用)算法 |
和LRU算法很相似 |
FIFO(先进先出)算法 |
有可能会抛弃重要的页面 |
第二次机会算法 |
比FIFO 有较大的改善 |
时钟算法 |
实际使用 |
LRU(最近最少)算法 |
比较优秀,但是很难实现 |
NFU(最不经常使用)算法 |
和LRU很类似 |
老化算法 |
近似LRU的高效算法 |
工作集算法 |
实施起来开销很大 |
工作集时钟算法 |
比较有效的算法 |
补充:
在 UNIX 系统中采用的页面置换算法是时钟CLOCK算法,
Windows NT的页面置换算法采用先进先出(FIFO)算法。