页面置换算法整理

页面置换算法

  • 页面置换算法的功能:当出现缺页异常,需调入新页面而内存已满时,置换算法选择被置换的物理页面。
  • 页面置换算法的设计目标:尽可能减少页面的调入调出次数,把未来不再访问或短期内不访问的页面调出。

置换算法确定我们现在在内存中工作集的内容,是哪些块。

最优页面置换算法

此算法不可能实现。在发生缺页中断的时候,在内存中的页面有的很快就会被访问,而有的页面可能要到10、100、1000条指令后才会被访问。此时要置换最迟被访问的页面,把因调用被替换的页面而引起的中断推迟到将来,越久越好。当缺页中断发生时,操作系统无法知道各个页面下一次将在什么时候被访问,因此这个算法是无法被实现的。

这个算法可以用来对其他可实现算法的性能进行比较

先进先出算法(First-In First-Out, FIFO)

vital

思路:选择在内存驻留时间最长的页面进行置换

实现:维护一个记录所有位于内存中的逻辑页面链表,链表元素按驻留内存的时间排序,链首最长,链尾最短,出现缺页时,选择链首页面进行置换,新页面加到链尾

特点:实现简单;性能较差,调出的页面可能是经常访问的

Belady异常:当为进程分配的物理块数增大时,缺页次数不减反增。

最近最久未使用算法 (Least Recently Used, LRU)

思路:选择最长时间没有被引用的页面进行置换,因为如果某些页面长时间未被访问,则它们在将来还可能会长时间不会访问

实现:缺页时,计算内存中每个逻辑页面的上一次访问时间,选择上一次使用到当前时间最长的页面

特点:可能达到最优的效果,维护这样的访问链表开销比较大

在缺页中断发生时,置换未使用时间最长的页面。

LRU理论上是可以实现的,但是代价很高。维护一个所有页面的链表,最近最多使用的页面在表头,最近最少使用的页面在表尾。困难的是在每次访问内存时都必须要更新整个链表。

假设用硬件实现:

  • 硬件有一个64位计数器C,它在每条指令执行完后自动加1,每个页表项必须有一个足够容纳这个计数器值的域。在每次访问完内存后,将当前的C值保存到被访问页面的页表项中。
  • 一旦发生缺页中断,操作系统就检查所有页表项中计数器的值,找到值最小的一个页面,这个页面就是最近最少使用的页面。
  • 但是只有非常少的计算机拥有这样的硬件

最不常用算法(Least Frequently Used, LFU)

思路:缺页时,置换访问次数最少的页面

实现:每个页面设置一个访问计数,访问页面时,访问计数加1,缺页时,置换计数最小的页面

特点:算法开销大,开始时频繁使用,但以后不使用的页面很难置换

时钟置换算法(Clock)

思路:仅对页面的访问情况进行大致统计

实现:

  • 在页表项中增加访问位,描述页面在过去一段时间的内访问情况。
  • 将各页面组织成环形链表,指针指向最先调入的页面。
  • 访问页面时,在页表项记录页面访问情况。(就是如果访问过了,就设置为1).
  • 缺页时,从指针处开始顺序查找未被访问的页面进行置换。(进行一次遍历,如果该位为1,则修改该位为0,进行下一个判断。)

特点:时钟算法是LRU和FIFO的折中

基于算法特性,第二轮扫描中一定会有为0的页表项,所以最多会进行两轮扫描。

改进型时钟置换算法(Advanced Clock)

时钟算法没有考虑页是否被修改过,对于同等情况下,为了减少写外存,没有被修改的页要被优先丢弃。

所以我们又加上了修改位,(0,没有,1,有)。

进行四轮扫描:

  1. 查找是否有没有被访问,又没有修改的页。(不修改标志
  2. 查找(0,1),修改访问位。
  3. 查找(0,0),不修改。
  4. 查找(0,1),一定找到,不修改。

工作集页面置换算法

extension not important

一个进程当前正在使用的页面的集合称为它的工作集。

若每执行几条指令就产生一次缺页中断,那么就称这个程序发生了颠簸。

在单纯的分页系统中,刚启动进程时,在内存中并没有页面。在CPU试图读取第一条指令时就会产生一次缺页中断,使操作系统装入含有第一条指令的页面,其他由访问全局数据和堆栈引起的缺页中断通常会紧接着发生。一段时间后,进程需要的大部分页面都已经在内存了,进程开始在较少缺页中断的情况下运行。这个策略被称为请求调页。

有不少分页系统会设法跟踪进程的工作集,以确保在让进程运行以前,它的工作集就已经在内存中了。该方法称为工作集模型,大大减少缺页中断率。在进程前装入其工作集页面也称为预先调页。工作集是随时间变化的。

事实上大多数程序会任意访问一小部分页面,工作集随时间缓慢变化。当程序重新开始时,就有可能根据它上次结束时的工作集对要用到的页面做一个合理的推测,预先调页就是在程序IXUS运行之前预先装入推测的工作集的页面。

按照以前的方法,定义工作集为前1000万次内存访问锁使用过的页面的集合,那么现在就可以这样定义:工作集即是过去10ms中的内存访问所用到的页面的集合。这样的模型很合适而且更容易实现。要注意到,每个进程只计算它自己的执行时间。

因此,如果一个进程在T时刻开始,在(T+100ms)的时刻使用了40msCPU时间,对工作集而言,它的时间就是40ms。一个程序从它开始执行到当前所实际使用的CPU时间总数通常称作当前实际运行时间。通过这个近似的方法,进程的工作集可以被称为在过去的τ秒实际运行时间中它所访问过的页面的集合。

基于工作集的页面置换算法就是找出一个不在工作集中的页面并淘汰它。每个表项至少包含两条信息:上次使用该页面的近似时间和R(访问位)。

过程:

  • 扫描所有的页面检查R位:
  • 若(R == 1)
    • 设置上次使用时间为当前实际时间,以表示缺页中断时该页面正在被使用
  • 若(R == 0 且生存时间>τ)
    • 移出这个页面,该页面在当前时钟滴答中未被访问,不在工作集中,用新的页面置换它。扫描会继续进行以更新剩余的表项。
  • 若(R == 0 且生存时间≤τ)
    • 记住最小时间。如果该页面R==0且生存时间小于或等于τ,则页面仍在工作集中。
    • 把页面临时保存下来,但是要记住生存时间最长(“上次使用时间”的最小值)。
    • 如果扫描完整个页表却没有找到合适的淘汰的页面,如果找到了一个或多个R == 0的页面,就淘汰生存时间最长的页面。

在最坏的情况下,在当前时钟滴答中,所有的页面都被访问过了,也就是所有的R都为1,因此就随机选择一个页面淘汰,如果有的话最好选一个干净页面。

工作集时钟页面置换算法

extension not important

在工作集页面置换算法中中,当缺页中断发生后,需要扫描整个页表才能确定被淘汰的页面,因此基本工作集算法是比较费时的。

基于时钟算法,并且使用了工作集信息,被称为WSClock(工作集时钟)算法。由于它实现简单,性能较好,所以在实际工作中得到了广泛应用。

与时钟算法一样,所需的数据结构是一个以页框为元素的循环表。

最初,该表示空的,当装入第一个页面后,把它加到该表中。随着更多的页面加入,它们形成一个环。每个表项包含来自基本工作集算法的上次使用时间,以及R位和M位。
与时钟算法一样,每次缺页中断时,首先检查指针指向的页面。

如果R位是1,该页面在当前时钟滴答中就被使用过,那么该页面就不适合被淘汰。然后把该页面的R位置为0,指针指向下一个页面,并重复该算法。

如果R位是0,查看生存时间,如果生存时间大于τ并且该页面是干净的,它就不在工作集中,而且在磁盘上它有一个有效的副本。申请此页框,并把新页面放在其中。如果该页面已经被修改过,就不立即申请此页框,为了避免由于调度写磁盘操作引起的进程切换,指针继续向前走,算法继续对下一个页面进行操作,有可能存在一个旧的而且干净的页面可以立即使用。

原则上,所有的页面都有可能因为磁盘I/O在某个时钟周期被调度,为了降低磁盘阻塞,需要设置一个限制,即最大只允许写回n个页面。一旦达到该限制,就不允许调度新的写操作。

指针经过一圈返回它的起点,有两种情况:

  1. 至少调用了一次写操作
  2. 没有调用过写操作

对于第一种情况,执行了写操作的页面已经不是干净的了,置换遇到的第一个干净页面,这个页面不一定是第一个被调度写操作的页面,因为硬盘驱动程序为了优化性能可能已经把写操作重排序了。

对于第二种情况,所有的页面都在工作集中,否则将至少执行了一个写操作。由于缺乏额外的信息,一个简单的方法就是随便置换一个干净的页面来使用,扫描中需要记录干净页面的位置。如果不存在干净页面,就选定当前页面并把它协会磁盘。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值