接下来我们介绍缺页异常
那么缺页异常呢
在我们前面讲页式存储管理里说
缺页异常就是发现页表项当中这一页
不在物理内存当中我就会产生缺页异常
缺页异常把相应的内容读到内存里头来
我再重新执行这条指令
这是我们前面对缺页异常的描述
那实际上在缺页异常里头呢
还有很多要处理的内容
我们现在先来介绍一下缺页异常的处理流程
那在这儿我们现在有一个图来说明这个过程
首先是我在CPU里头呢要访问一条指令
比如说load M
这条指令呢它会找m所对应的页表项
找到这一项之后 如果这一项是有效的
那这时候呢或者是驻留位是为1
好 这时候它就直接去访问去了
如果这一页是无效的
那这时候就会产生缺页异常
缺页异常呢就会导致操作系统的
缺页异常服务例程的执行
这个缺页异常服务例程它干什么呢
它缺页之后那首先第一个它得找到
对应着那一页在外存当中存在什么地方
如果说有这一页之后找到了
那这时候呢我把这一页读到内存里头来
读到内存里头来就会带来一个问题
我在内存里我到哪去找这一页
我肯定要找空闲的页面
如果找着那这时候呢我把这一页读进来
并且回身要修改相应的页表项
那页表项修改
修改完了之后然后我再重新执行这条指令
OK 这样以来的话 我这个缺页异常呢
就算是 大致的流程就算处理完了
但是在这个过程当中如果说
这个你要找空闲页找不着
那这时候怎么办呢
那这时候我们还需要把这个流程
再对这一段呢再做一个细化
那也就是我们这边说的
说我缺页异常我要在这里
要去找空闲的物理页面
如果能找着那这事没问题了
直接蹦到我们刚才说的复制
说的后面一步 如果没找着呢
那这时候我就得把另外一页把它写出去
我根据页面置换算法来找
找一页我不常用的我把它替换出去
假定说这一页的物理页帧号是F
它对应的逻辑页号是Q
好 我就找到这一项
那么找到这一项之后我把它淘汰掉
这时候我又有一个要判断的
这个Q对应的这一项是否修改过
如果修改过那你直接把它扔掉是不行的
我还必须把这一页呢写到外存当中去
给它找另外一个地方把它写那儿去
然后写完了之后呢
这一项我就可以拿回来用了
那在这之前呢还有一个事
要修改这个Q所对应的页表项的内容
把这一项置为是无效
以便于你下次再来访问的时候
这一项我已经分配给别人了
好 那如果说这写完了之后
那这时候E 就是我们刚才说到这儿
也就相当于我这儿有了一个空闲的页帧了
我把相应的这个P对应的这一页
把它装到这里头来 然后这是我们这里说的五这一步
修改P对应着的页表项的驻留位
表示这一页我已经把它对到这儿来了
好 然后这里的6对应这一步
我重新执行产生缺页异常的这一条指令
整个这个处理流程就算处理完了
那么有了这些介绍之后呢
我们说对这个缺页异常呢有一个了解
但是如果说你和实际的操作系统代码当中
缺页异常处理相比较这个流程仍然是非常简化
那实际代码里头比这处理又要复杂一些
这个希望大家再去看实际代码来逐步
把这个过程细化和加以理解
好 那接下来我们还有一个问题是说
我们刚才把在外存里找的那一页
外存那个地方我怎么去找它呢
那这个时候我的外存保存这一页放在哪
我必须很方便地找
在我们现在的操作系统里呢有两种搞法
一种搞法呢是说
我直接做一个分区叫兑换区
这在Linux Unix都是这么干的
另一个呢 我是可以用一个文件来存这些东西
在文件里头我采用特殊的格式
来映射这些页面
因为在这头我通常都是固定大小的页面
所以它的文件可以针对这种做法来做优化
好 这是我往哪放的事
这时候是不是所有东西
全放这里头呢也不是这样
因为我们在外存当中的这些
进程地址空间里的内容
有一些是我可以放到这里头兑换区里头的
而另外一些呢你比如说像我们这里说到
可能选择另外这样两种 一种是代码
我本来代码是在可执行文件里头的
那如果说你生生给它另整一个地方
去把它复制过去保存这是没必要的
所以这时候代码是直接指向你的可执行文件
而还有一些就是共享库 这些库呢 实际上
也是它有相应的目标文件来存放
这时候呢 你也没必要把它复制到这里头来
因为这两项内容呢我们都是不去修改的
好 其它的数据段 堆栈段那这些呢
你都可以放到你的兑换区里头
和兑换空间里头
好 最后一个问题我们来讨论
虚拟页式存储管理的性能
我们如何来评价
虚拟页式存储管理的性能呢
在这呢我们定义了一个指标
叫做有效存储访问时间
这个有效存储访问时间呢
如果说你是在页式存储管理里头没有虚拟的话
那么它就是访存的时间
因为我所有的内容都在内存里头
我直接读就可以 读内存的时间是固定的
大家是一致的 但是有了虚拟之后
那我们就只能有一部分是
直接从内存当中访问的
而另外一部分呢我是从硬盘上读的
那从硬盘上读呢 要涉及到缺页异常的处理时间
那这时候根据你缺页率
缺页率E减P那是你的内存访问
而概率P呢你是从硬盘上访问
这俩加到一起平均下来就是
你的存储访问的有效访问时间
那下面我们用一个例子来说
假定我访问内存的时间是10个纳秒
而一次访问磁盘的时间是5个毫秒
而在这里头缺页率设置为P
那缺页里头有一些需要做过修改的
页修改概率为Q 那这时候
我的有效存储访问时间是多少呢
在这儿这个表达 10纳秒乘以1减缺页率P
那这时候存储在内存里情况的访问
然后剩下的是会在磁盘上的访问
我们在这儿缺页异常处理时间
主要是你磁盘访问时间
而代码执行时间我们在这儿忽略不计了
好 那在这里头呢 基本上是说5个毫秒
是10个纳秒的50万倍
50万倍乘在这里头来
然后这边呢缺页率是概率P
然后在这里头呢它是乘1
还要加上一项什么呢
对于修改过的我是两个5毫秒
那这时候再加上一个Q
这个P乘Q是你这个缺页情况下再加上页修改
这俩搁在一起那最后是我们的有效时间
如果你想让这个最后这个
有效存储访问时间和这个10纳秒不相上下
或者稍微大一点的话
那么这个时候你的缺页率这个P必须足够小
以至于可以把这个50万倍基本上给抵消了
那这样以来的话我这个地方有效时间
才会可以和原来的存储访问相一致
那这是我们说虚拟页式存储管理的性能
那到这个地方呢
我们关于虚拟存储管理的概念就讲完了
那我们在这里还有一个问题没有涉及
就是我们在这里说我缺页中断
中断完了之后我要用页面置换算法
来选择一个页面来 用来存我先要加进来东西
那这个地方如何选择呢
这是我们下一次要讨论页面置换算法的内容
好 那今天的课就上到这里 下课