定义
- 虚拟存储器 := 主存&辅存地址空间统一编址
- 虚地址/逻辑地址 := 用户可自由编程的统一编址
- 实地址/物理地址 := 主存地址空间
- 工作原理
0. 前提:主辅存交流开销大
- 主存 as 辅存の Cache
- 全相联映射
- 回写法
典型虚存
- 页式虚拟存储器
- 段式虚拟存储器
- 段页式虚拟存储器
| 虚存类型 | 页 | 段 | 段页 |
|---|---|---|---|
| 单位大小 | 固定 | 不固定 分配后也可变长 |
|
| 对程序员透明 | ✅ 透明 | ❌ 不透明 低级语言 & 编译器 aware |
|
| 内存碎片 | 对内碎片 页表内碎片 最后一页浪费 |
对外碎片 主存上的段间碎片 |
|
| 与主存交换信息单位 | 页 | 段 | 页 |
| 分隔依据 | 定长分隔 | 逻辑分隔 便于编译、修改、共享、保护 |
页式虚拟存储器
- 静态原理
- 页表 :=
[装入位(1):脏位(1):替换控制位:物理地址]x页表项数- 装入位 := 是否已存在主存
虚拟地址:=[页号:页内地址]- 页表基址存储器 CR3 := 存页表所在地址
- 快表 TLB := 存页表热项的类 cache
- SRAM 实现
- 页表 :=
- 动态原理
页表项:=CR3+虚拟地址.页号- 先在 TLB 查是否有此项,miss 再查慢表
页表项.装入位=0$\Rightarrow$ OS 缺页异常页表项.装入位=1$\Rightarrow$物理地址:=[页表项.物理页号:虚拟地址.页内地址]
段式虚拟存储器
- 静态原理
- 段表 :=
[段首址:装入位:段长]x段表项数 虚拟地址=[段号:段内地址]- 段表基址存储器 := 存段表所在地址
- 段表 :=
- 动态原理
段表项:= 段表基址存储器 +虚拟地址.段号物理地址:=[段表项.段首址:虚拟地址.段内地址]
段页式虚拟存储器
- 原理:先分段,段内分页
虚拟地址:=[段号:段内页号:页内地址]- 优点:按段实现共享保护
- 缺点:两次查表,开销大
虚存缺失
缺失推断律
- Page miss $\implies$ Cache miss
- Page miss $\implies$ TLB miss
| 页表 Page | 缓存 Cache | 快表 TLB | 访存次数 | 说明 |
|---|---|---|---|---|
| ✅ hit | ✅ hit | ✅ hit | 0 | |
| ✅ hit | ✅ hit | ❌ miss | 1 | |
| ✅ hit | ❌ miss | ✅ hit | 1 | |
| ✅ hit | ❌ miss | ❌ miss | 2 | |
| ❌ miss | ❌ miss | ❌ miss | $\geq 2$ | 发生缺页异常,访问磁盘 |
虚存 vs Cache
- 相同点
- 不同点
- 【miss 开销】 虚存 miss 开销 $>$ cache miss 开销 主存辅存访存速度差距 100 倍,而 cache 主存访存速度差距 10 倍
- 【miss 解决】
- 虚存 miss $\Rightarrow$
- 先从辅存调到主存,CPU 才能继续访问
- CPU 与 miss 辅存不能直接通信
- cache miss $\Rightarrow$
- CPU 直接访问主存
- CPU 与 miss 主存可以直接通信
- 虚存 miss $\Rightarrow$
- 【问题导向】
- 虚存 $\Rightarrow$ 解决主存容量问题
- cache $\Rightarrow$ 解决系统速度问题
- 【透明性】
- 虚存 $\Rightarrow$ 对系统程序员不透明,对应用程序员透明
- cache $\Rightarrow$ 对所有程序员透明