Skip to content

请求页式管理

2026 大纲 三(二)2 请求页式管理

把"部分装入"这个想法真正做出来

上一节论证了为什么可以只装一部分——局部性原理让缺页变成偶发事件, 平摊下来性能损失可接受。但那只是可行性论证,具体怎么做还一件没说。

真做起来只需要回答两个问题:怎么知道要的东西不在内存, 以及发现不在之后怎么办

第一个问题好办。页表本来就是每次访存必查的,在页表项里加一个状态位就行—— 硬件查表时顺手看一眼,为 0 就说明不在。既然要加,索性把后面用得着的一起加上: 换出时该淘汰谁(访问字段 A)、换出要不要写回磁盘(修改位 M)、 去哪儿把它取回来(外存地址)。这四项就是请求分页相对基本分页的全部改动。

第二个问题麻烦一些,因为它发生在一条指令执行到一半的时候—— CPU 正在取操作数,突然发现这个操作数所在的页不在内存。 这条指令没法继续,也不能算失败,只能先放着,等页面调进来之后从头再执行一遍。 上一节说的"缺页必须是故障(Fault)而不是陷入(Trap)",指的就是这件事。

所以请求分页 = 基本分页 + 请求调页 + 页面置换。 这一节讲前两样,置换算法留给后面四篇。读的时候盯住两处: 哪些步骤是必做的、哪些只在内存满时才做, 以及一次缺页到底贵在哪——那个数字会直接决定后面所有置换算法存在的意义。

一、缺页中断的处理流程

访问的页面不在内存中(状态位 P=0)时产生缺页中断(Page Fault)

流程图上那句"从外存调入页面"是一次磁盘 I/O,毫秒量级,这段时间 CPU 不会干等:

阶段进程状态CPU 在做什么数据由谁搬
缺页中断被触发运行 → 阻塞执行缺页中断处理程序,启动磁盘 I/O——
磁盘读取中阻塞(挂在该 I/O 的等待队列上)被调度去运行别的进程磁盘控制器 / DMA,CPU 不参与搬运
I/O 完成阻塞 → 就绪响应磁盘的 I/O 完成中断(外中断),唤醒该进程——
再次被调度就绪 → 运行重新执行引起缺页的那条指令——

哪些是必做的,哪些只在内存满时才做

流程图上有一个分支,题目专挑这个分支问"一定包含还是不一定包含", 所以要把必做和可选分清楚:

步骤必做还是可选理由
保存现场、进入缺页处理程序必做任何中断都要做
分配页框必做调进来的页总得有地方放
淘汰内存中的页可选只在没有空闲页框时才需要。系统刚启动、或该进程的驻留集还没占满时,直接拿一个空闲页框即可
写回被淘汰的页可选即使发生了置换,也只在 M=1(脏页)时才写回
磁盘 I/O:把缺的页读进来必做这是缺页的定义
修改页表:填页框号、置存在位为 1必做否则重执行时还会缺页
恢复现场、重新执行该指令必做那条指令一次也没执行成功

所以"缺页处理一定会淘汰一个页"是错的——淘汰是"页框不够"的后果,不是"缺页"的后果。 两件事经常同时发生,但没有必然关系。

越界不属于缺页处理

还有一处边界要划清:地址越界和缺页是两个不同的异常,由两个不同的处理程序负责。

访问一个逻辑地址时,硬件先查越界(页号是否小于页表长度),越界就直接产生 地址越界异常,交给它自己的处理程序,结局是终止进程——这一步根本走不到查状态位。 只有越界检查通过、确认这个页确实属于本进程之后,才谈得上"它在不在内存"。

所以问"缺页处理过程中 OS 可能执行哪些操作"时,"处理越界错"不在其中; 而分配内存、页面置换、修改页表、磁盘 I/O 都在。

二、有效访存时间:口径先对,公式才有意义

缺页率的定义是:设访问页面成功的次数为 S、失败(需从外存调入)的次数为 F,总的页面访问次数 A=S+F,则 f=F/A。分母 A页面访问次数,也就是访存次数——这一点直接决定算例对不对:

题目给的说法它是什么口径怎么折算成 f
"缺页率为 f"每次访存直接用
"每访问 n 次内存缺页一次"每次访存f=1/n
"每执行 k 条指令缺页一次"每条指令先乘上每条指令的平均访存次数 c,再取倒数:f=1/(kc)

c 从哪来:一条指令至少要取指访存 1 次,再加上操作数的访存次数。所以"一条指令 = 一次访存"只在"零地址指令且不访问内存操作数"时成立,一般题目会给出或可从指令格式推出。

从"每 k 条指令缺一次页"折算到 EAT 的三步完整算例,含两条改进路线的敏感度对比(想看口径折算与期望加权怎么落到数上时展开)

某请求分页系统,一次内存访问 tmem=100 ns。缺页处理时:若被换出页未被修改,共需 tb=5 ms;若被换出页是脏页需先写回,共需 ta=8 ms。实测被换出页是脏页的概率 β=0.4。程序平均每条指令访存 2 次,实测每执行 1250 条指令发生 1 次缺页

第一步:把"每条指令"折算成"每次访存"

A=1250×2=2500 (次访存),f=FA=12500=4×104

EAT 公式里的 f每次访存的缺页概率,而题目给的是每条指令的口径。不乘那个 2,f 会大出一倍,最后的 EAT 也跟着错一倍。

第二步:按 β 加权求 tfault

tfault=βta+(1β)tb=0.4×8+0.6×5=3.2+3.0=6.2 ms=6.2×106 ns

一次缺页到底花 5 ms 还是 8 ms,取决于被淘汰的那一页脏不脏——这是个随机事件,只能取期望β 就是这个事件的概率。

第三步:代入 EAT

EAT=(1f)tmem+ftfault=0.9996×100+4×104×6.2×106=99.96+2480=2579.962580 ns

结论:EAT2580 ns,是纯内存访问(100 ns)的 约 25.8 倍,而缺页率只有万分之四。

敏感度:若把 β 从 0.4 降到 0(全靠改进 CLOCK 淘汰干净页),tfault 降到 5 ms,EAT 降到 99.96+2000=2100 ns——只优化"脏不脏"就省下 18%;而若把缺页率减半(f=2×104),EAT 降到约 1340 ns,省下 48%。两条改进路线的收益量级,这里一目了然。

三、请求分页的地址变换

在基本分页地址变换的基础上,增加了缺页中断处理和 TLB 管理:

  1. CPU 发出逻辑地址 → 拆分为页号 P 和偏移 W
  2. 查 TLB → 命中则直接得到页框号(命中时顺便由硬件置访问位 A;若是写操作还置修改位 M
  3. TLB 未命中 → 查内存中的页表
  4. 页表项 P=1(在内存)→ 把该页表项写入 TLB(快表满则按某种算法淘汰一项),计算物理地址
  5. 页表项 P=0(不在内存)→ 触发缺页中断 → 调入页面(必要时换出一页并使其 TLB 项失效)→ 更新页表和 TLB → 重新执行指令

第 5 步末尾的"重新执行"意味着这条流程会整个再走一遍,第二遍时在第 2 步就会命中 TLB。

考点速记

  1. 请求分页 = 基本分页 + 请求调页 + 页面置换。页表项在"页号 → 页框号"之外扩出四项:状态位 P(在不在内存)、访问字段 A(该淘汰谁)、修改位 M(换出要不要写回)、外存地址(去哪儿取)。
  2. A 与 M 由硬件在访存时自动置 1,软件只负责在合适时机清 0——访存每秒上亿次,任何软件参与都承受不起。
  3. 缺页处理里必做的是:分配页框 → 磁盘 I/O 调入 → 修改页表 → 重新执行原指令。可选的是:淘汰一个页(仅当无空闲页框)、写回被淘汰页(仅当 M=1)。⚠️"缺页一定会淘汰一个页"是错的——淘汰是"页框不够"的后果,不是"缺页"的后果
  4. 越界不属于缺页处理。越界检查在查状态位之前,越界就直接终止,根本走不到"在不在内存"这一步;两者是两个异常、两个处理程序。
  5. 一次缺页含两次中断:先内中断(缺页故障,CPU 内部条件触发),后外中断(磁盘 I/O 完成,外设信号触发)。
  6. 缺页期间进程阻塞、让出 CPU,数据由磁盘控制器 / DMA 搬运。所以一次缺页的代价除磁盘 I/O 外还含两次上下文切换
  7. 缺页属内中断的故障(Fault),判据是返回位置——调页就是修复,修复后原指令能成功执行,所以要重新执行当前条而不是下一条。另有两处特殊:它在指令执行期间产生;一条指令可能触发多次(指令本身跨页、多个操作数分落不同页),这直接决定了最少页框数
  8. TLB 一致性必须由 OS 显式维护:换出时必须让它的 TLB 项失效,否则后续访问会在 TLB 里命中一条指向已被别的页面占用的页框号、绕过页表读到错误数据。通用判据:凡会让页表项内容失效的动作都要同步作用到 TLB 上
  9. 换出要不要写回看 M:M=1 内存里的副本才是最新的,必须写回;M=0 与外存一致,直接丢弃。
  10. EAT=(1f)tmem+ftfault 是一次访存耗时的期望值。⚠️缺页率 f 的分母是访存次数不是指令条数——题目给"每执行 k 条指令缺一次"时须先乘每条指令的平均访存次数 c,即 f=1/(kc);忘了折算,结果整整差 c 倍。

这一节在真题里被考过的形式

考法分两类,且三道选择题问的是同一件事的三个切面——缺页处理到底包含哪些步骤。

  • 问缺页处理过程中 OS 执行的操作可能有哪些(2011-28)。答修改页表 + 磁盘 I/O + 分配页框,三条全对。这是最直白的一道,对照速记第三条的"必做"列即可。
  • 问用户进程访问内存产生缺页时,OS 可能执行的操作(2013-30)。答置换页 + 分配内存"处理越界错"不属于缺页处理。⚠️ 这就是速记第四条——越界和缺页是两个异常,越界在查存在位之前就已经把进程终止了。
  • 问缺页异常处理过程中"不一定"包含的操作(2022-29)。答淘汰内存中的页。⚠️ 另三项(建立页号与页框号的对应、把页读入内存、修改存在位)都是必做的。这道题专挑"必做 vs 可选"这个分界考,判据就一句:只有页框不够时才需要淘汰
  • 给页表和访问序列,算每次访存耗时并求物理地址(2009-46,大题)。走的是"查 TLB → 未命中查页表 → 有效位为 0 则缺页 → 处理后重新走一遍"这条完整回路。⚠️ 两处必错点:缺页那一次的耗时要把"重新执行"那一遍也算进去(先查 TLB 未命中、再查页表发现缺页、再处理、再重来一次),别只算一次;以及驻留集固定为 2 且用 LRU 局部淘汰时,第三次访问会把第一个页挤出去。

复习优先级必须拿满。 选择题只考速记第三、四条那两个分界(必做/可选、缺页/越界), 背清楚就是送分。大题走的是完整回路,练一遍 2009-46 即可, 关键是把"重新执行"那一遍的时间算进去。第十条那个缺页率分母的折算是全章最贵的一个坑, 虚拟存储性能与改进还会再用。

易错:认为缺页处理一定会淘汰一个页。只有无空闲页框时才淘汰

易错:把"处理越界错"算进缺页处理。越界检查在查存在位之前,是另一个异常、另一个处理程序。

易错:认为缺页期间 CPU 在等磁盘。进程阻塞让出 CPU,数据由 DMA 搬运,CPU 去跑别的进程了。

易错:认为一次缺页只有一次中断。两次——缺页故障(内中断)+ I/O 完成(外中断)。

易错:认为缺页处理完返回后执行下一条指令。它是故障,要重新执行当前这条

易错:算缺页率时拿指令条数做分母。分母是访存次数,给"每 k 条指令缺一次"时要乘每指令访存次数。

易错:认为页面换出后不用管 TLB。必须让它的 TLB 项失效,否则会读到别的页的数据。

易错:认为换出的页一律要写回磁盘。只有 M=1 才写回,M=0 直接丢弃。

教材出处
  • 缺页率的定义 f=F/AA=S+F 为总的页面访问次数)、以及缺页中断处理时间按脏页概率加权的公式 t=βta+(1β)tb:汤小丹《计算机操作系统》5.2.3 节「缺页率」,p162
  • 页面调入过程(保留 CPU 环境 → 分析中断原因 → 查页表得外存物理块 → 内存已满则先按置换算法选出换出页 → 修改位为 0 可不写回、为 1 必须写回 → 调入后修改页表项并将此页表项写入快表):同书 5.2.3 节「页面调入过程」,p162
  • 地址变换中"先检索快表,找到则修改页表项中的访问位;对写指令还须将修改位置 1"以及快表未命中时的处理:同书 5.2.1 节,p159
  • 含快表命中率 a 与缺页率 f 的有效访问时间展开式 EAT=λ+at+(1a)[t+f(ε+λ+t)+(1f)(λ+t)]:同书 5.3.5 节「访问内存的有效时间」,p168–169

相关知识

虚拟内存基本概念基本分页(地址变换)FIFO 页面置换算法中断和异常的处理页框分配与回收

真题练习