操作系统(thuOS)笔记(六) 第九讲 页面置换算法
9.1 置换算法的概念
功能和目标
页面锁定(frame locking)
把必须常驻的页面锁住——锁定标志位
评价方法
虚拟地址访问用(页号,页内偏移)表示,对应的页面轨迹用abcd代替
评价置换算法好坏的方法,即观察缺页次数
置换算法分类
局部页面置换算法
最优算法考虑未来情况,不能实现。先进先出实现简单,用FIFO就可以实现,但是对常用页面没有重视。时钟算法和最不常用算法都是最近最久未使用算法的近似。
全局页面置换算法
9.2 最优算法、先进先出算法和最近最久未使用算法
最优置换算法(OPT,optimal)
把内存中的页按下一次使用的时间排序,把最晚用的给置换出去
缺页最少,但是没法预知。
但是这种算法可以用来评价其他算法的优劣
示例:
访问e时,产生缺页,这时看到d是最晚用到的,所以把d置换出去
然后把d给替换出去,e替换进来
最终的缺页状况如下
先进先出算法(First-In First-Out, FIFO)
实现方法是维护一个记录所有位于内存中的逻辑页面链表
优点是简单,缺点也很明显,没有重视常用页面。
示例:假定初始的顺序是a->b->c->d,那访问e时,就把最先进来的a顶掉
最后执行完缺页5次
最近最久未使用算法(Least Recently Used,LRU)
思路是,以前常用的页面未来也常用
实现方法,相对于最优算法向后看,LKU是向前看
示例:
访问e时,往前看c是最久访问的,替换掉c
总共缺页3次
LRU算法的可能实现方法
页面链表,仿佛点到名字的同学站到第一个,需要替换时把排最后的请出去
活动页面栈,和链表很像,没什么优势
这两个算法开销都很大
用栈实现的示例
缺页时,把栈底的c替换掉
访问已有的页面时,还要将其抽到最顶
整体过程如下
9.3 时钟置换算法和最不常用置换算法
这两种方法是对FIFO的简化
时钟置换算法
LRU对过去的考虑过于详细,以至于开销很大,因此时钟置换算法只做粗略的统计。只是统计过去一段时间这个页面是否被访问过,访问过就留下。
维护一个环形链表,在页表项中增加访问位,指针指向最先调入的页面
实现算法为,访问页面时记录情况,缺页时指针顺序查找没有被访问的页面进行置换
时钟算法对过去的访问情况有考虑,又不像LRU考虑的很详细
实现方法
图示:开始时,指针位于页号0处。当访问的页不在内存中,指针开始按顺序移动
指针移动过程中,寻找访问位为0的页,并将遇到的访问位为1的页清零访问位。
找到后将访问位置1
再次缺页时再移动,周而复试地进行移动
改进的CLock算法
访问的一页是修改过的,则需要写回外存,再写入要读的一页,花的时间增加一倍。它的改进思路是,尽量不替换修改页
用一个表格来解释:没被使用没被修改则直接置换,没被使用但被修改则写回外存并清零修改位;使用过但没被修改则清零使用位;使用过且修改过则至少扫过两次才能置换,先清零使用位变成01的情况
改进过的Clock算法示例
加*表示修改过的内容还没有被写到外存中去,需要系统另外的部分进行处理
整体的图
最不常用算法(Least Frequently Used, LFU)
相比于时钟置换,用多位来表示使用频率
LFU的缺点是可能一个页面拿进来没用几次就被置换出去了,算法开销大。对技数比较大的会定期进行衰减右移(除以2)
LRU与LFU的区别,LRU需要维护栈,比较麻烦,LFU就相对简单一些
用具体例子说明,
本小节的两种算法,相对于LRU开销会小,但是统计精度也会下降。近似程度和准确性做折中。
9.4 Belady现象和局部置换算法比较
Belady现象
增加页面数,正常应该缺页率降低,把反而增加的现象称为Belady
产生Belady现象的原因是,标记的特征和内存访问的特征是不一致的。内存访问特征是多样的,比如一个排序算法,和一个Word文档编辑进程,它们的内存访问特征显然是不同的。
FIFO的示例来说明Belady现象
物理页面数为3,缺9页
物理页面数为4,缺10页
示例说明LRU算法没有Belady现象
LRU、FIFO、Clock的比较
LRU是最好的,FIFO是最差的
但是LRU在每一次访问时都要维护栈的顺序,开销比FIFO要大
LRU可以退化成FIFO。视频信息的输出时,从头到尾播一遍,每个物理内存访问一遍,FIFO就是个更好的选择。
Clock算法是LRU和FIFO的折中
Clock也可以退化成FIFO。
9.5 工作集置换算法
FIFO,3个物理内存放4页,有9次缺页;但是加一个物理内存页,缺页次数减一
可以看到,多分配一页,影响很大。在全局置换算法中,要考虑的就是这一点。
全局置换算法
比如说一个排序程序,刚开始时读入,中间一段是排序,最后一段是输出,这三个阶段就可以有不同的分配过程。
CPU利用率与并发进程数的关系
需要掌握一个合适的尺度,来提高CPU的利用率
毫不相关的几个进程会增加访存,导致缺页率增加,缺页处理增加CPU利用率下降
工作集
其定义如下,看着很复杂,实际跟图结合起来非常简单
进程的工作集示例
从t时间开始看:
W(t,10) = {1,2,5,6,7}
随着t向后移动,W也在发生变化,在t1和t2之间有一段时间,W是趋于稳定的。在不同阶段访问的页面数是不一样的。如果能在前面分配5页在后面分配2页,那就能很好地满足需求了。
根据工作集变化的趋势,可以分为过渡阶段和稳定阶段,这两个阶段是交替出现的。
如果给出的全局置换算法能够近似工作集变化曲线,那就会得到较好的效果。
由此定义了一个集合——常驻集
常驻集
工作集和常驻集的关系
缺页率与常驻集的关系
工作集置换算法
与局部置换算法的区别是,局部法缺页时把缺的那一页拿进来,然后根据不同的特征来把内存中的一页拿出去。而工作集置换算法运行的时刻未必是缺页的时刻。
此处工作集的定义是,当前时刻前τ个内存访问的页
实现方法是需要维护一个链表,访存时将不在工作集中的页面换出,缺页时换入页面。访存是很频繁的,做出换出的判断和动作开销很大;缺页时的开销却小了很多。
示例说明工作集置换算法
在当前时刻以前,按e->d->a顺序进入内存。t=1时,工作集为{e,d,a},c不在内存中,直接写入;t=2时,工作集为{d,a,c},访问c命中,同时把不在工作集中的e踢出去;t=3时,工作集为{d,c,a},写入b,都在工作集中不踢出;t=4时,工作集为{b,d,c},访问b命中,踢出a…最终结果如下
在访问时操作室很多的,维护的链表和LRU的栈很像,而且开销都很大
9.6 缺页率置换算法(PFF,Page-Fault-Frequency)
缺页率
前一种表达在缺页率算法中比较不好把握,因此多使用缺页平均时间间隔倒数来表达缺页率。
影响因素,我们能控制的是页面置换算法
缺页率置换算法
进程的物理页面数越多,缺页率越低。缺页率置换算法通过调节常驻集的大小,使每个进程的缺页率保持在一个合理的范围内。
当缺页率过高时,则增加物理页面数来降低缺页率
当缺页率过低时,并发度就会低,CPU利用效率也降低,则减少常驻集来减少物理页面数
实现方法
示例说明:t=1时缺页,直接写入c;一直t=4时缺页,时间间隔为3,大于2,把这段时间没有访问过的页面踢出,也就是a和e,此时留下c和d,加入b;一直到t=6时缺页,时间间隔为2,小于等于2,加入缺失页…最终结果如下
可以看到在运行时,常驻集数量是发生变化的。工作集置换算法在每次访存时都要进行判断和移动,而缺页率置换算法只在发生缺页时执行,只要间隔足够大就直接加入缺页,只有间隔小的时候才进行置换
9.7 抖动和负载控制
抖动(thrashing)
主要原因物理页面太少,频繁置换,开销变大,运行速度降低
我们的目标是,
负载控制
通过调节并发进程数(MPL)来进行系统负载控制
希望整个内存的大小,是整个进程工作集的总和
在CPU利用率到达顶点时,满足上述等式
但是上述方法是不容易衡量的,于是有了下面的表达
如果间隔大于处理时间,那么CPU是来得及完成的,CPU利用率在绿线红线交点之前;如果间隔小于处理时间,满负荷且忙不过来,