页面置换算法

705 阅读11分钟

页面置换算法

一、最佳置换OPT

1.1 思想

每次选择淘汰的页面将是以后永不使用,或者在最长时间内不再被访问的页面,这样可以++保证最低的缺页率++。

1.2 例子

假设系统为进程分配了三个内存块,执行过程中会依次访问到如下页面:7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1,其过程将会是:

访问次序 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K
页面序号 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
是否缺页 T T T T F T
内存块1 7 7 7 2 2
内存块2 0 0 0 0
内存块3 1 1 3

第一次访问,三个内存块都未被占用,所以刚开始的时候,按照页面的被访问顺序,7,0,1被依次放入内存块1,2,3;到第四次访问2号页时,根据算法思想:优先淘汰被访问的页面中,最长时间内不会再被访问到的页面,可以知道在已经被访问过的页面7,0,1中,0号页会在第五次被再次访问,1号页会在第E次被再次访问,7号页面会在第 I 次被再次访问,因此这里就优先淘汰掉7号页面,也就是7号页面可以被换出内存,然后放入下一个页面——2。

再后来进行第5次访问,且页号为0,发现0号页已经在内存中,因此不会发生缺页,所以页面情况不变(因而不想填)。

再后来进行第6次访问,且页号为3,发现3不在内存中,发生缺页,然后调度——发现在上一次(第5次)的访问中,2,0,1在页面中,并且2,0号页面在此后的访问中,顺序会先于1号页,因此置换出1号页,将3号页放入内存。如上表第6列。

以此类推,剩下的全部的顺序为:

访问次序 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K
页面序号 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
是否缺页 T T T T F T F T F F T F F T F F F T F F
内存块1 ++7++ 7 7 2 2 2 2 2 7
内存块2 ++0++ 0 0 0 4 0 0 0
内存块3 ++1++ 1 3 3 3 1 1

整个过程缺页中断发生了9次(T出现的次数),页面置换发生了6次。因此,++缺页时未必发生页面置换,because if there is available memory blocks for current process,就不用进行页面置换++。

缺页率=缺页次数/总共访问多少次页面=9/20=45%

1.3 Tip

so,OPT置换算法的前提是必须知道页面访问的页号和顺序,但实际上,只有在进程执行的过程中才能知道接下来会访问到的是哪个页面。操作系统无法提前预判页面访问序列,因此++最佳置换算法是无法实现的++。

二、先进先出置换 FIFO

2.1 思想

每次选择要淘汰的页面是最早进入内存的页面。

2.2 实现

把调入内存的页面根据调入的先后顺序排成一个队列,需要++换出页面时选择队头页面++即可。队列的最大长度取决于系统为进程分配了多少个内存块。

2.3 例子

假设系统为某进程分配了三个内存块,并考虑到有以下页面号引用串:3,2,1,0,3,2,4,3,2,1,0,4

根据FIFO思想,访问顺序情况应该如下:

访问次序 1 2 3 4 5 6 7 8 9 A B C
页面序号 3 2 1 0 3 2 4 3 2 1 0 4
是否缺页 T T T T T T T F F T T F
内存块1 ++3++ 3 3 0 0 0 4 4 4
内存块2 ++2++ 2 2 3 3 3 1 1
内存块3 ++1++ 1 1 2 2 2 0

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

2.4 Tip

只有FIFO算法会产生Belady异常。另外,FIFO算法虽然实现简单,但是该算法与进程实际运行时的规律不适应,因为先进入的页面也有可能最经常被访问。因此,FIFO算法性能差

三、最近最久未使用置换 LRU

3.1 思想

每次淘汰的页面是最近最久未使用的页面. Least Recently Used

3.2 实现

赋予每个页面对应的页表项中,用访问字段记录该页面自上次被访问以来所经历的时间++t++。当需要淘汰一个页面时,选择现有页面中++t++值最大的,即最近最久未使用的页面。

3.3 例子

4个内存块,页面引用顺序:1,8,1,7,8,2,7,2,1,8,3,8,2,1,3,1,7,1,3,7

访问顺序 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K
页面序号 1 8 1 7 8 2 7 2 1 8 3 8 2 1 3 1 7 1 3 7
是否缺页 T T F T F T F F F F T F F F F F T F F F
内存块1 ++1++ 1 1 1 1 1
内存块2 ++8++ 8 8 8 7
内存块3 ++7++ 7 3 3
内存块4 ++2++ 2 2

在第B次访问页面时,发现缺少页号为3的页面,从第B列往回走,发现第A、9、8、7次访问的页面依次是8,1,2,7. 说明最近最久未使用的页面就是7了,于是将7号置换出内存,再将页3调入内存

3.4 Tip

最近是指:离上一次不缺页状态的最近。

个人思考

感觉跟FIFO很像。不过还是有区别的——FIFO的处理办法就是单纯的先进先出,只要内存满了,并且发生缺页就淘汰掉队头页面,这样的话只要它是First in,可能导致使用最频繁的页面被频繁调出/入内存—,FIFO是不需要时刻与这些页面保持一个追踪关系的;LRU则需要时刻追踪这些页面。怎么说,因为根据LRU的思想,要判断出谁是Least Recently Used page,就必须要存储这些页面的Last Visit Time。所以根据前面的对比可以发现,++LRU is more efficient++ than FIFO and having ++more hits++ than FIFO because LRU ++keeps in memory the recently used pages++.

这里有一个很形象的例子:FIFO与LRU对比

四、时钟置换CLOCK

4.1 思想

Also called NRU,Not Recently Used.

4.2 实现

为每个页面设置一个访问位R,再将内存中的页面都通过链接指针链接成一个循环队列。当某页被访问时,其R位被置为1。当需要淘汰一个页面时,只需检查页的R位。如果是0,就选择该页换出;如果是1,则将它置为0,暂不换出,继续检查下一个页面。

若第一轮扫描中所有页面R位都是1,则将这些页面的R位依次置为0后,再进行第二轮扫描。

第二轮扫描中一定会有R位为0的页面,因此简单的CLOCK算法选择一个淘汰页面最多会经过两轮扫描

4.3 例子

假设系统为某进程分配了个内存块,并考虑到有以下页面号引用串:

1,3,4,2,5,6,3,4,7

开始正常访问,前5个被依次装入内存块,R位为1,循环队列为:++1(R=1) → 3(R=1) → 4(R=1) → 2(R=1) → 5(R=1) → 1++;在访问6号页面时,发生缺页错误,于是考虑置换。然后从循环队列中的链接指针当前指向的位置开始扫描并尝试找到一个R位为0的页面,并且如果是1的话还要将其改为0。

所以第一次扫描完成之后的循环队列为:++1(R=0) → 3(R=0) → 4(R=0) → 2(R=0) → 5(R=0) → 1++,链接指针当前指向的R位置为1,R=0;淘汰1号页并将其置换出内存,再调入6号页面,R=1;,++指针指向下一个页面 3,并修改 R=0++;此时的队列为:++6(R=1) → 3(R=1) → 4(R=1) → 2(R=1) → 5(R=1) → 6++。

接下来访问3号页,3在内存中,将3号页面的R位置为1即可,4同理。

4.4 Tip

++应当注意的是,只有在发生置换的时候指针才会移动++,so此时的指针仍然指向3号页面,队首是3所在的节点。

所以访问到7进而发生缺页的时候,指针从3开始依次扫描到4,4的R≠0,修改4的R=0;扫描到2,2的R=0,置换出2,调入7,修改7的R=1;++指针指向下一个页面5,修改5的R=0++;此时的队列为:++6(R=1) → 3(R=1) → 4(R=1) → 7(R=1) → 5(R=0) → 6++。

五、改进型时钟置换

简单的时钟置换算法仅考虑到一个页面最近是否被访问过。事实上,如果被淘汰的页面没有被修改过,就不需要执行I/0操作写回外存。++只有被淘汰的页面被修改过时,才需要写回外存++。

5.1 思想

除了考虑一个页面最近有没有被访问过之外,操作系统还应考虑页面有没有被修改过。在其他条件都相同时,应优先淘汰没有修改过的页面,避免I/O操作。

Explaining:NRU makes approximation to replace the page based on ++R and M bits++. When a process is started up, ++both page bits for all pages are set to 0++ by operating system. ++Periodically++, the R bit is cleared, to distinguish pages that have not been referenced recently from those that have been. When page fault occurs, the operating system inspects all the pages and divide them into 4 categories based on current values of their R and M bits.

  • Case 0 : not referenced, not modified;++(R, M) = (0, 0)++

  • Case 1 : not referenced, modified;++(R, M) = (0, 1)++

  • Case 2 : referenced, not modified;++(R, M) = (1, 0)++

  • Case 3 : referenced, modified;++(R, M) = (1, 1)++

5.2 实现

新增一个修改位M,M=1代表页面近期被修改过,0没有。用(R位,M位)的形式表示各页面状态。

将所有可能被置换的页面排成一个循环队列

第一轮:从当前位置开始扫描到第一个(0,0) 的帧用于替换。本轮扫描不修改任何标志位

第二轮:若第一轮扫描失败,则重新扫描,查找第一个(0,1)的帧用于替换。本轮将所有扫描过的帧R位设为0

第三轮:若第二轮扫描失败,则重新扫描,查找第一个(0,0)的帧用于替换。本轮扫描不修改任何标志位

第四轮:若第三轮扫描失败,则重新扫描,查找第一个(0,1) 的帧用于替换。

由于第二轮已将所有帧的访问位设为0,因此经过第三轮、第四轮扫描一定会有一个帧被选中,因此++改进型CLOCK置换算法++选择一个淘汰页面++最多会进行 4 轮扫描++。

5.3 例子

The NRU (Not Recently Used) algorithm removes a page at random from the lowest numbered nonempty class. In given example:

  • Page-0 is of class-2 (referenced, not modified);++(R, M) = (1, 0)++

  • Page-1 is of class-1 (not referenced, modified);++(R, M) = (0, 1)++

  • Page-2 is of class-0 (not referenced, not modified);++(R, M) = (0, 0)++

  • Page-3 is of class-3 (referenced, modified);++(R, M) = (1, 1)++

    So ++lowest class++ Page-2 need to be replaced by NRU, and then class Page-1 pages and so on.

5.4 Tip

RM, 00,01,10,11. 意会。

待定,不知道

六、Summary

规则 优缺点
OPT 优先淘汰最长时间内不会被访问的页面 缺页率小,性能最好,无法实现
FIFO 优先淘汰较先进入内存的页面 实现简单,性能差,Belady异常
LRU 优先淘汰最近最久没访问的页面 性能很好,开销大
CLOCK 循环扫描,第一轮淘汰R=0,并修改R为1; 实现简单,开销小,不考虑页面是否被修改过
NRU 第一轮淘汰(0,0)
第二轮淘汰(0,1)并修改R为0
第三轮淘汰(1,0)
第四轮淘汰(1,1)
开销小,性能好

至于NRU第几轮到底先淘汰哪一个,还没找到同一版本

~原唱Queen乐队,外链没版权翻唱凑合。~