第十讲 · 虚拟存储、中断与 DMA

对应材料:2025 计组复习提纲“虚拟存储器”“微处理器集成”。

程序发出的地址为什么能相同而互不冲突?内存不够时为什么程序还能运行?设备比 CPU 慢几个数量级,CPU 又怎样不被它拖住?

这两组问题分别由地址转换和 I/O 协作机制解决;它们最终在异常、中断和操作系统处理程序处汇合。

1. 虚拟地址与物理地址

CPU 中的程序使用虚拟地址(VA),真正送到主存的是物理地址(PA)。内存管理单元 MMU 完成转换:

CPU 产生 VA → MMU 地址转换 → PA → Cache / 主存

虚拟存储带来:

  • 每个进程都有独立、连续的虚拟地址空间;
  • 不同进程的同一 VA 可映射到不同物理位置;
  • 页面权限可以隔离进程并保护内核;
  • 当前不需要的页面可暂存磁盘,程序可使用大于物理主存的地址空间。

2. 分页:地址低位不需要转换

虚拟空间按固定大小分成虚拟页,物理主存按同样大小分成物理页框。地址拆成:

VA=VPN∥Offset,VA=VPN\Vert Offset, PA=PPN∥Offset.PA=PPN\Vert Offset.

页内偏移 Offset 原样保留,只把虚拟页号 VPN 换成物理页号 PPN。

若页大小为 2p2^p byte,则偏移为 pp bit。4 KB 页面有 12 位偏移。

2.1 课件例题

32 位虚拟地址、128 MB 物理主存、4 KB 页面:

VPN 位数=32−12=20,VPN\text{ 位数}=32-12=20, PPN 位数=log⁡2(128 MB)−12=27−12=15.PPN\text{ 位数}=\log_2(128\text{ MB})-12=27-12=15.

因此:

  • 虚拟空间最多有 2202^{20} 个虚拟页;
  • 物理主存有 2152^{15} 个页框;
  • 一个进程不可能让所有虚拟页同时驻留主存。

3. 页表:用 VPN 查 PPN

页表可先理解为数组:VPN 是下标,数组元素是页表项 PTE。PTE 不只保存 PPN,还可能包含:

字段作用
Valid / Present页面是否已在主存
AR读、写、执行等访问权限
Dirty驻留后是否被修改
Ref / Accessed最近是否被访问
PPN 或磁盘位置在主存时给页框,不在时记录后备位置

每个进程有自己的页表。操作系统切换进程时,把该进程页表在主存中的基地址写入 PTBR(Page Table Base Register)。

3.1 页表为何也很大

32 位 VA、4 KB 页面共有 2202^{20} 个虚拟页。若每个 PTE 为 4 B,单级页表就要

220×4 B=4 MB.2^{20}\times4\text{ B}=4\text{ MB}.

页表本身放在主存中。如果每次读数据都要先读一次 PTE,再读真正数据,访存次数几乎翻倍,于是需要 TLB。

4. 页命中与缺页

4.1 页命中

PTE 表示页面已经在主存:取出 PPN,与原 Offset 拼成 PA,继续访问 Cache/主存。

4.2 缺页

若页面不在主存,产生缺页异常。CPU 不会让当前 load 读到一个“空值”,而是停止并交给操作系统:

  1. 用 VPN 找到页面在磁盘的位置;
  2. 找空闲物理页框;若主存满,选择牺牲页;
  3. 若牺牲页 Dirty,先写回磁盘;
  4. 从磁盘把所需页读入页框;
  5. 更新新旧 PTE,并使失效的 TLB/Cache 状态保持一致;
  6. 返回后重新执行发生缺页的指令。

重新执行很关键:原指令此前没有完成,不能从下一条继续。

虚拟存储访问流程:TLB、页表、缺页、页面替换与 Cache

图源:2025 复习提纲的完整数据访问流程。图中 P 代表虚拟页。

5. 为什么虚拟存储必须重视 Dirty

主存与磁盘的性能差距极大,不能每次写内存都同步写磁盘。虚拟存储采用写回思想:先只改主存页面并置 Dirty,页面被替换时才写回后备存储。

  • Dirty=0:磁盘副本仍是最新,牺牲时可直接覆盖页框;
  • Dirty=1:页面已被修改,替换前必须写回,否则数据丢失。

页面通常比 Cache 块大得多,例如页面 4 KB、Cache 块 64 B。缺页代价也远高于 Cache 缺失,因此页面替换更谨慎,课件强调基于 Ref 的 LRU 思路。

6. TLB:页表项的 Cache

TLB(Translation Lookaside Buffer)保存最近用过的 VPN→PPN 映射:

  1. 用 VPN 查 TLB;
  2. 命中则直接得到 PPN;
  3. 缺失才访问主存中的页表;
  4. 页表命中后,把 PTE 装入 TLB;
  5. 页表也缺失则触发缺页处理。

TLB 可以是全相联或组相联。表项一般包含 Valid、Dirty、Ref、AR、TLB Tag 与 PPN。

6.1 组相联 TLB 例题

课件参数:16 KB 页面、40 位 VA、64 GB 主存、2 路组相联 TLB,共 512 项。

Offset=log⁡2(16 KB)=14 bit,Offset=\log_2(16\text{ KB})=14\text{ bit}, VPN=40−14=26 bit,VPN=40-14=26\text{ bit}, PPN=log⁡2(64 GB)−14=36−14=22 bit,PPN=\log_2(64\text{ GB})-14=36-14=22\text{ bit}, 组数=512/2=256,TLBIndex=8 bit,\text{组数}=512/2=256,\qquad TLBIndex=8\text{ bit}, TLBTag=26−8=18 bit.TLBTag=26-8=18\text{ bit}.

若状态位为 Valid 1 位、Dirty 1 位、Ref 1 位、AR 2 位,则表项总位数为

1+1+1+2+18+22=45 bit.1+1+1+2+18+22=45\text{ bit}.

7. TLB、页表、Cache 的先后关系

在课件的物理地址 Cache 模型中:

VA = VPN | Offset
      ↓ 查 TLB
   得到 PPN
      ↓ 拼接
PA = PPN | Offset
      ↓ 查 Cache
   得到数据

为什么先查 TLB?因为 Cache 的 Tag/Index 来自物理地址,在得到 PPN 前还没有完整 PA。

7.1 各种“缺失”不能画等号

情况是否可能解释
TLB miss,页表 hit可能映射在主存页表,但没缓存在 TLB
TLB hit,Cache miss可能地址转换命中,但数据块没在 Cache
TLB miss,转换后 Cache hit可能先查页表得到 PA,数据块仍可能在 Cache
Page fault,Cache hit不可能页面不在主存,物理 Cache 不应有该页的有效数据

TLB miss 是“翻译缓存没找到”,Page fault 是“页面本身不在主存”,Cache miss 是“所需物理数据块不在 Cache”。三者发生在不同层。

8. 页面替换与状态一致性

替换一个物理页框时,不能只覆盖 DRAM:

  • 旧页 PTE 要改为不驻留,并记录磁盘位置;
  • 旧 VPN 对应的 TLB 项要失效;
  • 若 Cache 中还有该物理页的数据,相关块不能继续被当作旧映射的有效数据;
  • 新页 PTE 要写入新 PPN,随后才能重启访问。

课件用 Ref 表示近期访问。真正的精确 LRU 成本可能很高,系统可周期清 Ref,用近似算法判断哪些页面长期没被访问。

9. I/O 为什么不能照 CPU 速度来

鼠标、网络、磁盘等设备速度相差巨大,也普遍远慢于 CPU。I/O 接口通常提供:

  • 状态寄存器:设备是否 ready、是否出错;
  • 数据寄存器:CPU 与设备交换的数据;
  • 控制寄存器:启动、方向、中断使能等。

10. 程序查询:最简单,也最浪费 CPU

CPU 反复读状态寄存器:

do {
    status = device.status;
} while (!status.ready);

data = device.data;

优点是控制简单;缺点是等待期间 CPU 一直执行无效循环。设备越慢,浪费越严重。

11. 中断:设备准备好后主动通知

中断是设备产生的异步事件,与当前指令没有因果关系。课程模型中的过程:

  1. 设备拉高中断请求 Int;
  2. CPU 完成当前指令;
  3. 把下一条指令地址 PC+4PC+4 保存到 EPC;
  4. PC 跳到固定 ISR 入口 0xBFC00000;
  5. 中断服务程序保存现场、服务设备、恢复现场;
  6. eret 把 EPC 恢复到 PC,继续原程序。

ISR 框架:

保存可能被破坏的寄存器
读取设备状态,判断中断原因
与设备交换数据并确认/清除请求
恢复寄存器
eret

12. EXL:防止同一个中断反复重入

设备可能一直保持中断请求,直到 ISR 真正访问设备寄存器清除它。若 CPU 刚进 ISR 执行一条指令又响应同一电平,就会不断跳回 ISR 开头。

课程模型用状态寄存器中的 EXL 位:

  • 正常执行时 EXL=0,允许响应;
  • 进入 ISR 同时置 EXL=1,屏蔽再次进入;
  • eret 恢复 EPC 的同时清 EXL=0。

真正的中断机制是软硬件协同:设备发请求,控制器在指令边界检测,EPC/EXL 保存最小硬件状态,ISR 再用软件保存完整现场。

13. 异常与中断

课件把异常定义为 CPU 执行指令产生的同步事件,例如溢出、除 0、非法指令、TLB 缺失。

对比异常中断
与指令流关系同步,有因果关系异步,无因果关系
受害指令尚未完成,停止执行当前指令先完成
EPC 保存当前指令地址下一条指令地址
返回后常需重试受害指令从下一条继续

两者处理骨架相似:保存位置、进入处理程序、保存/恢复现场、特殊返回。区别决定 EPC 中究竟应该放当前 PC 还是 PC+4PC+4。

课件的控制状态机为中断增加 INT 状态,为异常增加 EXC 状态:非法指令可在译码阶段发现,溢出在 ALU 运算阶段发现。控制器必须保证异常指令不产生部分写入,才能实现精确恢复。

14. DMA:批量数据不再让 CPU 逐字搬运

中断避免了忙等,但若每传一个字都中断一次,CPU 仍要执行大量 I/O 指令。DMA(Direct Memory Access)让控制器直接在设备和主存之间搬一整块数据。

DMA 控制器通常含:

  • Address:当前主存/设备地址;
  • Counter:剩余传输量;
  • Control:方向、中断使能等;
  • Status:完成或错误状态;
  • 数据缓冲与总线接口逻辑。

14.1 DMA 的三个阶段

  1. CPU 初始化:设置方向、设备地址、主存起始地址、长度和完成中断;
  2. DMA 传输:申请总线,读源、写目的,地址递增、计数递减;
  3. 后处理:整块完成后产生一次中断,CPU 检查结果或提交下一块。

DMA 获得总线时,CPU 可能暂时无法访问主存,这仍是一种资源竞争;但相比 CPU 为每个字执行 load/store,整体效率高得多。

15. 三种 I/O 方式放在一起

方式等待由谁承担数据由谁搬CPU 开销适合场景
程序查询CPU 忙等CPU最高极简单、极短操作
中断 I/O设备就绪时通知CPU/ISR中等零散事件、低速设备
DMADMA 控制器DMA最低高速、批量传输

16. 完整系统的一次 load

一条 lw 的真实路径可以这样串起来:

  1. 流水线 E 级用 ALU 算 VA;
  2. VPN 查 TLB;
  3. TLB miss 时查页表,Page fault 时异常进入 OS、从磁盘调页;
  4. PPN 与 Offset 拼成 PA;
  5. PA 查 Cache;
  6. Cache miss 时从主存装入数据块;
  7. 数据沿流水线写回目标寄存器;
  8. 若等待磁盘 I/O,设备完成后还可能用 DMA 搬数据并以中断通知 CPU。

从一条指令到整个系统,核心始终是三问:状态在哪里、谁产生下一状态、结果什么时候可用。

评论