虚拟存储器的基本概念

虚拟存储器是三级层次中的第二个缓存对:主存—辅存。它与 Cache 用的是同一个思想(把常用的放上一级),但解决的矛盾不同:Cache 解决速度,虚拟存储器解决容量。

从计组的角度看,虚拟存储器只有一件事:地址转换。 程序里的地址是虚拟的,实际访问的是物理主存,中间那一层翻译必须由硬件在每一次访存时完成。至于哪些页该留在主存、页满了淘汰谁、怎样避免抖动,那是操作系统的工作,在 OS 3.2里展开。

两科的分界线就是这条:计组管翻译的硬件通路,操作系统管替换的策略。

机制

虚拟地址空间与实地址空间

程序按虚拟地址(逻辑地址)编写和编译,虚拟地址空间的大小由指令中的地址字段位数或CPU 的虚拟地址位数决定,与实际装了多少内存无关。

主存按物理地址(实地址)访问,物理地址空间的大小由主存容量决定。虚拟地址地址转换(硬件)物理地址转换失败(要访问的页不在主存)时产生缺页,由操作系统调页。

三个必要条件

虚拟存储器能工作,需要三样东西同时具备:

  1. 局部性——保证绝大多数访问能在主存命中(见 3.5.1)
  2. 地址转换机构——把虚地址翻译成实地址,必须是硬件,因为每一次访存都要做一遍
  3. 缺页处理机制——必须能中断当前指令并在处理后重新执行它,这就是故障(Fault)类异常的定义

第三条是虚拟存储器对 CPU 提出的硬性要求:指令必须可以在执行到一半时被打断、并在缺页处理完后从头重来。没有这个能力就无法支持请求调页。

三种实现方式

方式划分单位单位大小表一次转换查几次表
页式页(等长)固定,2 的幂页表1 次
段式段(按逻辑)可变段表1 次
段页式先分段、段内分页段可变、页固定段表 + 页表2 次

三者分别在 3.6.2、3.6.3、3.6.4展开。

与 Cache 的分工

两个缓存对同时在工作,而且是串联的:

flowchart LR
    VA["虚拟地址"] --> MMU["地址转换<br/>(TLB / 页表)"]
    MMU --> PA["物理地址"]
    PA --> CACHE{"Cache 命中?"}
    CACHE -->|"是"| OK["取数"]
    CACHE -->|"否"| MEM["访问主存"]
    MMU -.->|"页不在主存"| PF["缺页异常<br/>交操作系统"]

    classDef os fill:#fadbd8,stroke:#c0392b
    classDef hw fill:#d5f5e3,stroke:#27ae60
    class PF os
    class MMU,CACHE hw

顺序是”先翻译、后查 Cache”(在最常见的物理索引物理标记的 Cache 下)。这意味着一次访存最多可能要经历三层未命中:TLB 未命中 → 查页表;页不在主存 → 缺页;Cache 未命中 → 访主存。完整讨论见 3.6.2。

边界

虚拟存储器的容量不等于主存加辅存之和。 它由虚拟地址的位数决定(上限),实际可用还受辅存容量限制。“虚存容量 = 主存 + 辅存”是错的。

地址转换必须由硬件完成,缺页处理必须由软件完成。 这两条各有理由:转换发生在每一次访存上,软件做不起;缺页要启动 I/O、耗时毫秒,硬件包办会让 CPU 空等。这正是 3.1.3 那条层次辨析的具体化。

虚拟存储器对应用程序透明,对操作系统不透明。 与 Cache 的”对两者都透明”不同,这是 3.6.5的核心对照项。

“虚拟存储器”和”虚拟内存”在 408 里指同一件事,前者是计组的叫法,后者是操作系统的叫法。

Cache 与虚拟存储器是并存的两级,不是二选一。 一道题若问”有了 Cache 还需要虚拟存储器吗”,答案是需要——它们解决的是不同的矛盾。

对照速查

Cache—主存主存—辅存(虚拟存储器)
解决速度容量
单位块(行)页 / 段
管理全硬件硬件(转换)+ OS(替换)
对应用透明是是
对 OS 透明是否
未命中硬件处理,无中断缺页异常,OS 处理

考点

  • 虚拟存储器是主存—辅存层次,解决容量矛盾
  • 三个必要条件:局部性、硬件地址转换机构、可重执行的缺页机制
  • 地址转换由硬件做,缺页处理由操作系统做
  • 虚存容量由虚拟地址位数决定,不是主存加辅存
  • 对应用程序透明,对操作系统不透明
  • Cache 与虚拟存储器串联并存,先翻译后查 Cache
  • 三种实现:页式(1 次查表)、段式(1 次)、段页式(2 次)

链接