在为进程分配物理块时,又将涉及到这样三个问题:
最小物理块数的确定
显然,给每个进程所分配物理块数目越少,则进程执行中的缺页率越高,进程的执行速度也减慢。为使进程能有效地工作,应为它分配一定数目的物理块。
最小物理块数:是指能保证进程正常运行所需的最少物理块数。若系统为某进程所分配的物理块数少于此值时,进程将无法运行。
进程应获得的最少物理块数与计算机的硬件结构有关,取决于指令的格式、功能和寻址方式。
例:对于某些简单的机器,若是单地址指令且采用直接寻址方式,则所需的最少物理块数为 2。如果该机器允许间接寻址时,则至少要求有物理块数为 3。对于前面所介绍的在缺页中断机构中要发生 6 次中断的情况,至少要为每个进程分配 6 个物理块,以装入 6 个页面。
物理块的分配策略
物理块的分配算法
在采用固定分配策略时,如何将系统中可供分配的所有物理块分配给各个进程,可采取下述几种方法。
解决的问题:
系统应当在何时把一个页面装入内存?
可采用一种以预测为基础的预调页策略,将那些预计在不久之后便会被访问的页面,预先调入内存。
处理过程:
请求调页:仅当进程执行过程中,通过检查页表发现相应页面不在内存时,才装入该页面。
当进程刚开始执行时,由于预先未装入进程的页面,故需要频繁地申请装入页面。执行一段时间以后,进程的缺页率将下降。
采用请求调页方式,磁盘 I/O 的启动频率较高,系统的开销较大。
在请求分页系统中的外存分为两部分:用于存放文件的文件区和用于存放对换页面的对换区。
通常,由于对换区是采用连续分配方式,而文件区是采用离散分配方式,故对换区的磁盘 I/O 速度比文件区的高。
这样,每当发生缺页请求时,系统应从何处将缺页调入内存,可分成如下三种情况。
整个页面的调入过程对用户是透明的。
页面置换算法的选择,是虚拟存储器管理系统的核心问题。
它的实质是,为系统提供一种方法,当从主存中需要换出页面时,应避免选择那些不久将再次要求访问的页面。
置换算法的选择在一定程度上取决于可用的硬件设施。
最理想的页面置换策略是:从主存中移出永远不再需要的页面;如无这样的页面存在,则应选择最长时间不需要访问的页面。
最佳置换策略首先是由 Belady 于 1966 年提出的。
最佳置换策略本身不是一种实际的方法,因为页面访问的未来顺序是不知道的,但是,可将其它的实用方法与之比较来评价这些方法的优劣。所以,这种最佳策略具有理论上的意义。
例 设页面请求次序 7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1
存储块为 3(驻留集为 3),假定最初存储块为空,采用 OPT。
第一行为要请求访问的页面,第二行为存储块(内存)中存储的页,第三行为被移出内存的页。
从上面的演示知,利用 OPT,发生了 6 次页面置换,发生了 9 次缺页中断(前 3 次没有置换,但内存中未装入页面,发生中断)
缺页率=缺页次数/访问次数=9/20=0.45
该算法的实质是:总是选择作业中驻留时间最长的一页淘汰。即先进入主存的页面先退出主存。
算法实现比较容易,如分配给一个作业的存储块数为 m,只需建立一个 m 个元素的队列表 Q(0)、Q(1)、…、Q(m-1)和一个替换指针。该队列是按页面调入主存的先后顺序排列的,而指针始终指向最早调入主存的一页。
发生了12次页面置换,发生了15次缺页中断,缺页率=缺页次数/访问次数=15/20=0.75
二次机会算法是 FIFO 算法的升级版,而 clock 算法可以认为是二次机会算法的升级版本
该算法仍然使用标准的 FIFO 队列。
每个帧(frame)有一个 second chance 位,也叫做引用位。
当一个 frame 被引用到,它的 second chance 位设置为 1。这表示该 frame 后面还有可能会被引用到,所以下次置换先跳过这个 frame,也就是再给它一次机会留在内存中。这样可以减少 frame 置换,提高页面操作效率。
当一个新的页面被读到内存中时,它的 second chance 被设置为 0。
当你需要替换内存中的一个页面时,使用轮询的方式来查找可以被替换的页面:
LRU(least Recently Used)算法的基本思想是,利用局部性原理,根据一个作业在执行过程中过去的页面访问踪迹来推测未来的行为。它认为过去一段时间里不曾被访问过的页面,在最近的将来可能也不会再被访问。
算法的实质是:当需要置换一页面时,选择在最近一段时间内最久未使用的页面予以淘汰。
实现这种技术,是通过周期性地对“页面访问”位进行检查,并利用它来记录一个页面自上次访问以来所经历的时间 t,并选择 t 为最大的页予以淘汰。
发生了9次页面置换,发生了12次缺页中断,缺页率=缺页次数/访问次数=12/20=0.60
LRU 算法的硬件支持
LRU 算法作为页面置换算法是比较好的,因为它适用于各种类型的程序。但是,实现起来比较困难,因为要对先前的访问历史时时加以记录和更新。如果这种连续的修改完全由软件来做,系统开销太大;如由硬件执行,则需要解决:
为此,需要以下两类硬件的支持:
移位寄存器:
为了记录某进程在内存中各页的使用情况,须为每个在内存中的页面配置一个移位寄存器可表示为:
$R = R_{n-1}R_{n-2}R_{n-3}…R_2R_1R_0$
当进程访问某物理块时,要将相应寄存器的最高位$R_{n-1}$位置成 1。表示这个页面最近被访问过。系统每隔一定时间(例如 100 ms)将寄存器右移一位,这意味着如果一个页面在一段时间内没有被访问,它的寄存器值将逐渐变小。
如果我们把 n 位寄存器的数看作是一个整数,那么,具有最小数值的寄存器所对应的页面,就是最近最久未使用的页面。
例如,假设我们有三个页面,其寄存器值分别为 100(4)、010(2)和 001(1)。在这种情况下,第三个页面的寄存器值最小,因此它是最近最久未使用的页面,应该被换出。
栈
操作系统维护一个栈,其中每个元素代表一个页面。栈顶的元素代表最近被访问的页面,而栈底的元素代表最近最久未使用的页面。
最少使用置换算法(Least Frequently Used)选择到当前时间为止被访问次数最少的页面被置换。
1、基本方法:
记录每个页面的访问次数,最少访问的页面首先考虑淘汰
2、实际采取方法
为页面设置移位寄存器。统计 1 的个数,1 的个数越少,表示访问次数越少,越容易被淘汰。
与 LRU 的区别:
R1=10000000
R2=01110100
LRU----------淘汰 R2
LFU----------淘汰 R1
简单的 Clock 置换算法(NRU)当采用简单 clock 算法时,为每页设置一位访问位,再将内存中的所有页面都通过链接指针链接成一个循环队列。
系统把一个页面移出内存时,如果该页面驻留内存期间没有被修改过,那么不必把它写回辅存,否则系统必须把它写回辅存。这表明,换出未修改过的页面比换出被修改过的页面开销小。
显然,我们可以依据上述结论改进 CLOCK 算法。改进后的 CLOCK 算法将在置换范围内首选符合下面条件的作为被置换页面
由访问位 A(Access)和修改位 M(Modify)可以组合成下面四种类型的页面,淘汰优先级依次下降:
1 类(A=0,M=0):表示该页最近既未彼访问,又未被修改,是最佳淘汰页。
2 类(A=0,M=1):表示该页最近未被访问,但已被修改,并不是很好的淘汰页。
3 类(A=1,M=0):最近已被访问,但未被修改:该页有可能再被访问。
4 类(A=1,M=1):最近已被访问且被修改,该页可能再被访问。
执行过程可分成以下三步:
(1)从指针所指示的当前位置开始,扫描循环队列,寻找 A=0 且 M=0 的第一类页面,将所遇到的第一个页面作为所选中的淘汰页。在第一次扫描期间不改变访问位 A。
(2)如果第一步失败,即查找一周后未遇到第一类页面,则开始第二轮扫描,寻找 A=0 且 M = 1 的第二类页面,将所遇到的第一个这类页面作为淘汰页。在第二轮扫描期间,将所有扫描过的页面的访问位 A 都置 0。
(3)如果第二步也失败,亦即未找到第二类页面,则将指针返回到开始的位置,并将所有的访问位复 0。然后重复第一步,如果仍失败,必要时再重复第二步,此时就一定能找到被淘汰的页 .
Q:存储块越多,缺页中断率越小吗?
A:
一般来说,对于任何一个页的访问顺序(或序列)和任何一种换页算法,如果分给的物理块数增加,则缺页(所访问页不在主存)的频率应该减少。但这个结论并不普遍成立,对于某些页面访问序列,FIFO 有随着分给的页架数增加,缺页频率也增加的异常现象。
例如某程序在内存中分配 m 页初始为空,页面走向为
1,2,3,4,1,2,5,1,2,3,4,5
当 m=3,m=4 时缺页中断分别为多少?用 FIFO 算法
m=3 时,缺页中断 9 次
m=4 时,缺页中断 10 次
有效访问时间是指访问存储器所需时间的平均值。
假设使用了快表,则 CPU 访问内存时有以下三种情况(设内存读写周期为 t,查找快表时间为 λ,缺页中断处理时间为 ɛ):
引入快表命中率为 α,缺页中断率为 f,则有效访问内存时间为:
EAT= α(λ + t) + [1-α](2(λ + t) + f(2(λ + t) + ɛ))
系统内进程增多–>每个进程的缺页率增大–>缺页率增大到一定程度,进程总等待调页完成–>CPU 利用率降低–>进程进一步增多,缺页率更大 …
此时: 进程调入一页,需将一页淘汰出去,刚淘汰出去的页马上要需要调入;称这一现象为抖动或颠簸(thrashing)显然,防止的根本手段给进程分配足够多的帧
抖动:如果运行进程的大部分时间都用于页面的换入/换出,而几乎不能完成任何有效的工作,则称此进程处于抖动状态。抖动又称为颠簸。
抖动分为:
抖动产生的原因有:
在工作集模型中,工作集的定义是在最近的一段连续执行时间(称为工作集窗口,通常用 T 表示)内,进程实际引用过的页面集合。换句话说,工作集是进程当前正在使用或可能马上就要使用的页面的集合。
工作原理:请求分段系统中,程序运行之前,只需先调入若干个分段(不必调入所有的分段),便可启动运行。当所访问的段不在内存中时,可请求 OS 将所缺的段调入内存。
为了实现请求调段、分段置换两大功能,系统必须提供如下的硬件支持:
在虚拟存储系统中的所有段表,其段描述子增加五个信息标识位。
段名 | 段长 | 段的机制 | 存取方式 | 状态位 P | 访问位 A | 修改位 M | 增补位外存地址 |
---|
由上述段表机制知道,状态位记录了访问段是否在内存。在地址映射过程中,在段表中发现所要访问的段不在内存,则产生缺段中断。OS 接到此中断信号后,就调出缺段中断处理程序,根据段表中给出的外存地址,将该段调入内存,使作业继续运行下去。缺段中断与缺页中断类似,主要表现为:
① 一个缺段中断要求在指令执行中间得到服务,即发现所要访问的指令或数据不在内存时产生缺段中断并处理。
② 一条指令可能引起多次不同的缺段中断。
为了实现分段共享,可在系统中配置一张共享段表,所有共享段都在共享段表中占有一个表项。
共享段的分配
在为共享段分配内存时,对第一个请求使用该共享段的进程,由系统为该共享段分配一物理区,再把共享段调入该区,同时将该区的始址填入请求进程的段表的相应项中,还须在共享段表中增加一表项,填写有关数据,把 count 置为 1;
之后,当又有其它进程需要调用该共享段时,由于该共享段已被调入内存,故此时无须再为该段分配内存,而只需在调用进程的段表中,增加一表项,填写该共享段的物理地址;在共享段表中,填上调用进程的进程名、存取控制等,再执行count+=1
操作,以表明有两个进程共享该段。
共享段的回收
当共享此段的某进程不再需要该段时,应将该段释放, 包括撤消该进程段表中共享段所对应的表项,以及执行 count-=1
操作。
若 count 结果为 0,则须由系统回收该共享段的物理内存,以及取消在共享段表中该段所对应的表项,表明此时已没有进程使用该段;否则,则只是取消调用者进程在共享段表中的有关记录。
环保护的基本原则是:
一个程序可以访问驻留在相同环或较低特权环中的数据;
一个程序可以调用驻留在相同环或较高特权环中的服务。
环保护的基本思想是将操作系统内的操作和资源划分为不同的"环",每个环都有其特定的权限。通常,环的编号越小,权限越高。例如,在一个典型的四环模型中:
Storage Management PartⅢ