598 lines
18 KiB
Markdown
598 lines
18 KiB
Markdown
# 14. 分页存储管理
|
||
|
||
> **课程**: 操作系统 - 存储器管理
|
||
> **核心内容**: 碎片问题、分页思想、地址结构、页表、地址变换、TLB快表、多级页表、倒转页表
|
||
|
||
---
|
||
|
||
## 前置知识
|
||
|
||
- [[13_存储管理基础]] — 存储器层次结构、逻辑地址与物理地址、MMU
|
||
- [[01_系统运行机制]] — CPU工作模式与硬件基础
|
||
|
||
---
|
||
|
||
## 一、碎片问题
|
||
|
||
在连续分配方式中,内存中会出现无法被利用的空闲区域,称为**碎片**。
|
||
|
||
| 碎片类型 | 出现位置 | 产生原因 | 对应分配方式 |
|
||
|---------|---------|---------|------------|
|
||
| **内碎片** (Internal Fragmentation) | 分配区域**内部** | 固定分区大小 > 进程实际需要 | 固定分区分配 |
|
||
| **外碎片** (External Fragmentation) | 分配区域**外部** | 空闲分区太小,无法满足任何请求 | 动态分区分配 |
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
subgraph 内碎片示意
|
||
direction TB
|
||
A1["┌──────────────┐"]
|
||
A2["│ 进程实际数据 │"]
|
||
A3["│──────────────│"]
|
||
A4["│ 未使用空间 │ ← 内碎片"]
|
||
A5["└──────────────┘"]
|
||
end
|
||
|
||
subgraph 外碎片示意
|
||
direction TB
|
||
B1["┌────┐ ┌────┐ ┌────┐ ┌────┐"]
|
||
B2["│进程A│ │空闲│ │进程B│ │空闲│"]
|
||
B3["└────┘ └────┘ └────┘ └────┘"]
|
||
B4[" ↑外碎片 ↑外碎片"]
|
||
end
|
||
```
|
||
|
||
> **根本原因**: 无论是固定分区还是动态分区,都要求进程在内存中**连续存放**。要彻底解决碎片问题,必须放弃"连续"要求——这就是**分页**思想的核心出发点。
|
||
|
||
---
|
||
|
||
## 二、分页的基本思想
|
||
|
||
分页存储管理将**虚拟地址空间**和**物理内存**都划分为大小相等的小块:
|
||
|
||
- 虚拟地址空间的每一块称为**虚拟页 (Virtual Page, VP)**
|
||
- 物理内存的每一块称为**物理页框 (Page Frame, PF)**
|
||
|
||
常见的页面大小为 $2^k$ 字节:512B、1KB、2KB、**4KB**(最常用)。
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph VA["虚拟地址空间 (进程视角)"]
|
||
direction TB
|
||
VP0["虚拟页 VP0"]
|
||
VP1["虚拟页 VP1"]
|
||
VP2["虚拟页 VP2"]
|
||
VP3["虚拟页 VP3"]
|
||
VP4["..."]
|
||
end
|
||
|
||
subgraph PM["物理内存"]
|
||
direction TB
|
||
PF0["物理页框 PF0"]
|
||
PF1["物理页框 PF1"]
|
||
PF2["物理页框 PF2"]
|
||
PF3["物理页框 PF3"]
|
||
PF4["..."]
|
||
end
|
||
|
||
VP0 -->|"页表映射"| PF2
|
||
VP1 -->|"页表映射"| PF0
|
||
VP2 -->|"不在内存"| DISK["外存(磁盘)"]
|
||
VP3 -->|"页表映射"| PF3
|
||
|
||
style VA fill:#e3f2fd,stroke:#1976d2
|
||
style PM fill:#fff8e1,stroke:#f9a825
|
||
style DISK fill:#fce4ec,stroke:#c62828
|
||
```
|
||
|
||
**关键特性**:
|
||
- 虚拟页在物理内存中**不需要连续**存放
|
||
- 每个虚拟页可以映射到任意一个空闲物理页框
|
||
- 消除了外碎片(但每个页内可能有少量内碎片)
|
||
|
||
---
|
||
|
||
## 三、地址结构
|
||
|
||
在分页系统中,虚拟地址被划分为两部分:
|
||
|
||
```
|
||
虚拟地址 VA (v+k 位)
|
||
┌─────────────────┬─────────────┐
|
||
│ VPN (v位) │ VPO (k位) │
|
||
│ 虚拟页号 │ 页内偏移 │
|
||
└─────────────────┴─────────────┘
|
||
```
|
||
|
||
**计算公式**:
|
||
- 页大小 = $2^k$ 字节
|
||
- 虚拟页号 VPN = $\lfloor VA / 2^k \rfloor$(即高位部分)
|
||
- 页内偏移 VPO = $VA \mod 2^k$(即低 $k$ 位)
|
||
|
||
物理地址同理:
|
||
|
||
```
|
||
物理地址 PA (p+k 位)
|
||
┌─────────────────┬─────────────┐
|
||
│ PPN (p位) │ PPO (k位) │
|
||
│ 物理页号 │ 页内偏移 │
|
||
└─────────────────┴─────────────┘
|
||
```
|
||
|
||
- 物理页号 PPN 由页表查得
|
||
- **PPO = VPO**(页内偏移不变,直接复制)
|
||
|
||
### 地址计算示例
|
||
|
||
> **例题**: 某系统虚拟地址 16 位,页面大小 4KB ($2^{12}$),求虚拟地址 VA = 0x3A6F 对应的 VPN 和 VPO。
|
||
|
||
- 页大小 $2^k = 2^{12}$,所以 $k = 12$,$v = 16 - 12 = 4$
|
||
- VPN = $0x3A6F / 0x1000 = 0x3$(高4位:0011)
|
||
- VPO = $0x3A6F \mod 0x1000 = 0xA6F$(低12位)
|
||
|
||
```
|
||
VA = 0x3A6F = 0011 1010 0110 1111
|
||
──── ────────────────
|
||
VPN VPO
|
||
(0x3) (0xA6F)
|
||
```
|
||
|
||
---
|
||
|
||
## 四、页表
|
||
|
||
页表是实现虚拟页到物理页框映射的核心数据结构。
|
||
|
||
### 页表结构
|
||
|
||
每个进程拥有**独立的页表**。页表以 VPN 为索引,每个页表项 (PTE) 包含:
|
||
|
||
```
|
||
页表 (以VPN为索引)
|
||
┌──────┬───────┬──────────────────────────────┐
|
||
│ VPN │ PPN │ 控制位 │
|
||
├──────┼───────┼──────────────────────────────┤
|
||
│ 0 │ 5 │ V=1 D=0 R=1 W=1 U/S=1 │
|
||
│ 1 │ 2 │ V=1 D=1 R=1 W=1 U/S=1 │
|
||
│ 2 │ --- │ V=0 (不在内存) │
|
||
│ 3 │ 8 │ V=1 D=0 R=1 W=0 U/S=1 │
|
||
│ ... │ ... │ ... │
|
||
└──────┴───────┴──────────────────────────────┘
|
||
```
|
||
|
||
### 页表项 (PTE) 各字段
|
||
|
||
| 字段 | 含义 | 说明 |
|
||
|------|------|------|
|
||
| **有效位 (Valid/Present)** | 页面是否在内存中 | V=1:在内存;V=0:不在内存(缺页) |
|
||
| **修改位 (Dirty)** | 页面是否被写过 | D=1:被修改过,换出时需写回外存 |
|
||
| **引用位 (Reference)** | 页面是否被访问过 | 用于页面置换算法(如Clock、LRU近似) |
|
||
| **读/写权限 (R/W)** | 读写保护 | 只读页被写入时触发保护异常 |
|
||
| **用户/内核 (U/S)** | 访问权限 | U=0:仅内核可访问;U=1:用户可访问 |
|
||
| **物理页号 (PPN)** | 对应的物理页框号 | 与VPO拼接得到物理地址 |
|
||
|
||
---
|
||
|
||
## 五、地址变换过程
|
||
|
||
### 基本地址变换流程
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["CPU发出虚拟地址 VA"] --> B["从VA中提取VPN和VPO"]
|
||
B --> C{"TLB查找VPN"}
|
||
C -->|"TLB命中"| D["直接取出PPN"]
|
||
C -->|"TLB未命中"| E["访问页表<br/>(页表基址寄存器PTBR + VPN × PTE大小)"]
|
||
E --> F{"页表项有效位?"}
|
||
F -->|"V=1"| G["取出PPN"]
|
||
F -->|"V=0"| H["**缺页中断**<br/>操作系统处理"]
|
||
H --> I["从外存调入页面"]
|
||
I --> J["更新页表"]
|
||
J --> G
|
||
D --> K["物理地址 PA = PPN × 2^k + PPO"]
|
||
G --> K
|
||
K --> L["访问物理内存"]
|
||
|
||
style H fill:#ffcdd2,stroke:#c62828
|
||
style C fill:#e8f5e9,stroke:#2e7d32
|
||
```
|
||
|
||
### 详细步骤
|
||
|
||
1. **提取地址字段**: 从虚拟地址 VA 中分离出 VPN 和 VPO
|
||
2. **查TLB**: 用 VPN 在 TLB 中查找(见第六节)
|
||
3. **查页表**: 若 TLB 未命中,用 **PTBR(页表基址寄存器)+ VPN** 定位页表项
|
||
4. **检查有效位**:
|
||
- V=1:取出 PPN,与 PPO 拼接得到物理地址
|
||
- V=0:触发**缺页中断**,OS 从外存调入页面
|
||
5. **拼接物理地址**: PA = PPN | PPO(将 PPN 放高位,PPO 放低位)
|
||
|
||
### 缺页中断处理流程
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["发生缺页中断"] --> B["保存CPU现场"]
|
||
B --> C{"外存中找到该页?"}
|
||
C -->|"找到"| D{"内存有空闲页框?"}
|
||
C -->|"未找到"| E["终止进程<br/>(非法访问)"]
|
||
D -->|"有空闲"| F["从外存读入该页"]
|
||
D -->|"无空闲"| G["执行页面置换算法<br/>选择牺牲页"]
|
||
G --> H{"牺牲页Dirty=1?"}
|
||
H -->|"是"| I["将牺牲页写回外存"]
|
||
H -->|"否"| J["直接覆盖"]
|
||
I --> F
|
||
J --> F
|
||
F --> K["修改页表<br/>设置V=1, PPN"]
|
||
K --> L["重新执行被中断的指令"]
|
||
```
|
||
|
||
### 地址变换计算示例
|
||
|
||
> **例题**: 某系统页面大小 1KB ($2^{10}$),虚拟地址 14 位。页表如下,求虚拟地址 VA=0x1A8F 对应的物理地址。
|
||
|
||
| VPN | PPN | Valid |
|
||
|-----|-----|-------|
|
||
| 0 | 3 | 1 |
|
||
| 1 | 7 | 1 |
|
||
| 2 | --- | 0 |
|
||
| 3 | 5 | 1 |
|
||
| 4 | 2 | 1 |
|
||
| 5 | 8 | 1 |
|
||
| 6 | 1 | 1 |
|
||
|
||
**解题过程**:
|
||
|
||
1. 页面大小 $2^{10}$,所以 $k=10$,$v=14-10=4$
|
||
2. VA = 0x1A8F = **01 1010 1000 1111** (二进制)
|
||
- VPN = 高4位 = 0110 = **6**
|
||
- VPO = 低10位 = 10 1000 1111 = 0x28F
|
||
3. 查页表:VPN=6 对应 PPN=**1**,Valid=1
|
||
4. PA = PPN | PPO = 1 × 2^{10} + 0x28F = 0x400 + 0x28F = **0x68F**
|
||
|
||
```
|
||
VA = 0x1A8F: 0110 1010001111
|
||
VPN=6 VPO=0x28F
|
||
|
||
查页表: VPN=6 → PPN=1
|
||
|
||
PA = 0001 1010001111 = 0x068F
|
||
PPN=1 PPO=0x28F
|
||
```
|
||
|
||
---
|
||
|
||
## 六、TLB 快表
|
||
|
||
### TLB 概述
|
||
|
||
**TLB (Translation Lookaside Buffer)** 是集成在 MMU 中的高速缓存,存储最近使用的页表项。
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
CPU["CPU"] -->|"虚拟地址"| TLB{"TLB<br/>(快表)"}
|
||
TLB -->|"命中<br/>取出PPN"| PA["物理地址"]
|
||
TLB -->|"未命中"| PT["查页表<br/>(内存)"]
|
||
PT -->|"PPN"| PA
|
||
PT -->|"更新TLB"| TLB
|
||
|
||
style TLB fill:#e8f5e9,stroke:#2e7d32
|
||
style PT fill:#fff3e0,stroke:#e65100
|
||
```
|
||
|
||
### TLB 组织方式
|
||
|
||
| 方式 | 说明 | 特点 |
|
||
|------|------|------|
|
||
| **全相联** | VPN可以放在TLB的任意位置 | 灵活但查找慢,适合小容量TLB |
|
||
| **组相联** | VPN映射到固定的组(set),组内任意放置 | 折中方案,最常用 |
|
||
| **直接映射** | VPN映射到固定的TLB位置 | 最快但冲突多 |
|
||
|
||
### TLB 性能分析
|
||
|
||
设 TLB 查找时间为 $\lambda$,内存访问时间为 $t$,TLB 命中率为 $a$:
|
||
|
||
**无 TLB 时**:每次地址变换需要访问一次页表(内存)+ 一次数据访问(内存)
|
||
|
||
$$EAT_{无TLB} = t + t = 2t$$
|
||
|
||
**有 TLB 时**:
|
||
|
||
$$EAT = a(\lambda + t) + (1-a)(\lambda + t + t) = \lambda + t + (1-a) \cdot t$$
|
||
|
||
> **计算示例**: 设 $\lambda = 10$ns, $t = 100$ns, $a = 0.98$(98%命中率)
|
||
>
|
||
> $EAT = 10 + 100 + (1 - 0.98) \times 100 = 10 + 100 + 2 = 112$ ns
|
||
>
|
||
> 相比无TLB的 $2t = 200$ ns,性能提升了约 **44%**。
|
||
|
||
---
|
||
|
||
## 七、多级页表
|
||
|
||
### 为什么需要多级页表
|
||
|
||
对于 32 位系统,页面大小 4KB:
|
||
- 虚拟地址空间 = $2^{32}$ = 4GB
|
||
- 页数 = $2^{32} / 2^{12} = 2^{20}$ = 1M 个页
|
||
- 每个页表项 4 字节 → 页表大小 = 1M × 4B = **4MB**
|
||
|
||
4MB 的页表对于每个进程都太大了!而且页表必须连续存放。
|
||
|
||
### 二级页表结构
|
||
|
||
**核心思想**: 将页表本身也分页,用"页目录"来索引这些页表页。
|
||
|
||
```
|
||
32位虚拟地址 (二级页表)
|
||
┌──────────────┬──────────────┬──────────────┐
|
||
│ 页目录索引(10位)│ 页表索引(10位) │ 页内偏移(12位)│
|
||
└──────────────┴──────────────┴──────────────┘
|
||
```
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
CR3["CR3<br/>(页目录基址)"] --> PD["页目录<br/>(1024项)"]
|
||
PD -->|"页目录项"| PT1["页表1<br/>(1024项)"]
|
||
PD -->|"页目录项"| PT2["页表2<br/>(1024项)"]
|
||
PD -->|"页目录项"| PT3["页表3<br/>(1024项)"]
|
||
PT1 -->|"页表项+偏移"| PF1["物理页框"]
|
||
PT2 -->|"页表项+偏移"| PF2["物理页框"]
|
||
PT3 -->|"页表项+偏移"| PF3["物理页框"]
|
||
|
||
style PD fill:#e3f2fd,stroke:#1976d2
|
||
style PT1 fill:#fff3e0,stroke:#e65100
|
||
style PT2 fill:#fff3e0,stroke:#e65100
|
||
style PT3 fill:#fff3e0,stroke:#e65100
|
||
```
|
||
|
||
### 多级页表的优势
|
||
|
||
- 页目录只需常驻内存(4KB),页表页按需创建
|
||
- 未使用的虚拟地址区域**不需要分配页表页**,节省大量内存
|
||
- 64 位系统通常使用 **3~5 级页表**(如 Linux 的 4 级页表:PGD→PUD→PMD→PTE→偏移)
|
||
|
||
### 二级页表地址变换
|
||
|
||
1. 用 CR3 找到页目录基址
|
||
2. 用**页目录索引**在页目录中找到页表页的物理地址
|
||
3. 用**页表索引**在页表页中找到 PPN
|
||
4. PPN 与**页内偏移**拼接得到物理地址
|
||
|
||
> **注意**: 二级页表需要 **3 次内存访问**(页目录 + 页表 + 数据),比一级页表多一次。因此 TLB 的作用更加重要。
|
||
|
||
---
|
||
|
||
## 八、倒转页表
|
||
|
||
### 基本思想
|
||
|
||
传统页表以**虚拟页号**为索引,每个进程一张。倒转页表以**物理页框号**为索引,整个系统一张。
|
||
|
||
| 对比项 | 传统页表 | 倒转页表 |
|
||
|--------|---------|---------|
|
||
| 索引 | 虚拟页号 (VPN) | 物理页框号 (PFN) |
|
||
| 表项数 | 虚拟页数(可能很大) | 物理页框数(固定) |
|
||
| 进程数 | 每进程一张 | 全系统一张 |
|
||
| 查找方式 | 直接索引 | 需要搜索(或用Hash) |
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
subgraph 传统页表
|
||
direction TB
|
||
T1["VPN 0 → PPN x"]
|
||
T2["VPN 1 → PPN y"]
|
||
T3["VPN 2 → PPN z"]
|
||
T4["..."]
|
||
end
|
||
|
||
subgraph 倒转页表
|
||
direction TB
|
||
I1["PFN 0 ← VPN a, 进程P1"]
|
||
I2["PFN 1 ← VPN b, 进程P2"]
|
||
I3["PFN 2 ← VPN c, 进程P1"]
|
||
I4["..."]
|
||
end
|
||
```
|
||
|
||
**优点**: 表大小与物理内存成正比,节省空间(尤其在 64 位系统)
|
||
|
||
**缺点**: 查找需要搜索整个表(通常用 Hash 加速)
|
||
|
||
---
|
||
|
||
## 九、内存保护
|
||
|
||
分页系统中通过以下机制实现内存保护:
|
||
|
||
### 1. 越界保护
|
||
|
||
- 页表项中的有效位 V=0 表示该页不在内存,访问时触发缺页中断
|
||
- 非法虚拟地址(超出进程地址空间范围)触发保护异常
|
||
|
||
### 2. 标志位保护
|
||
|
||
| 标志位 | 保护功能 |
|
||
|--------|---------|
|
||
| R/W | 读/写权限控制。只读页被写入时触发异常 |
|
||
| U/S | 用户/内核权限。用户态访问内核页时触发异常 |
|
||
| NX (No Execute) | 禁止执行位。数据页被当作代码执行时触发异常 |
|
||
|
||
### 3. 键保护
|
||
|
||
- 每个物理页框有一个保护键 (Protection Key)
|
||
- 每个进程有一个键寄存器
|
||
- 只有键匹配时才允许访问
|
||
- Intel MPX/MPK 技术支持此机制
|
||
|
||
---
|
||
|
||
## 十、空闲页面管理
|
||
|
||
操作系统需要跟踪物理内存中哪些页框是空闲的:
|
||
|
||
### 1. 位示图法 (Bitmap)
|
||
|
||
用一个 bit 表示一个物理页框的状态:0=空闲,1=已分配。
|
||
|
||
```
|
||
位示图示例 (假设16个物理页框):
|
||
位号: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
||
状态: 1 1 0 1 0 0 1 1 0 1 0 0 1 1 0 1
|
||
↑ ↑ ↑
|
||
空闲 空闲 空闲
|
||
```
|
||
|
||
- **优点**: 简单,查找连续空闲块方便
|
||
- **缺点**: 位示图本身占用内存(物理内存 4GB、页大小 4KB → 位示图 128KB)
|
||
|
||
### 2. 链表法
|
||
|
||
将所有空闲页框用链表串起来:
|
||
|
||
```
|
||
空闲链表: [PF3] → [PF5] → [PF8] → [PF12] → NULL
|
||
```
|
||
|
||
- **优点**: 实现简单,不额外占用大量空间
|
||
- **缺点**: 查找连续空闲块需要遍历链表
|
||
|
||
---
|
||
|
||
## 十一、Nachos 页式存储管理代码
|
||
|
||
Nachos 教学操作系统中实现了基本的分页存储管理。以下是关键代码片段:
|
||
|
||
### 核心数据结构
|
||
|
||
```cpp
|
||
// 页表项结构 (Machine/translate.h)
|
||
typedef struct {
|
||
int virtualPage; // 虚拟页号 (VPN)
|
||
int physicalPage; // 物理页号 (PPN)
|
||
bool valid; // 有效位
|
||
bool readOnly; // 只读标志
|
||
bool use; // 引用位 (用于LRU等算法)
|
||
bool dirty; // 修改位
|
||
} TranslationEntry;
|
||
```
|
||
|
||
### 地址转换核心代码
|
||
|
||
```cpp
|
||
// Machine/translate.cc - translate()
|
||
// 将虚拟地址转换为物理地址
|
||
int Machine::Translate(int virtAddr, int *physAddr, int size, bool writing) {
|
||
// 1. 计算VPN和偏移
|
||
int vpn = virtAddr / PageSize;
|
||
int offset = virtAddr % PageSize;
|
||
|
||
// 2. 查找页表
|
||
TranslationEntry *entry = &pageTable[vpn];
|
||
|
||
// 3. 检查有效位
|
||
if (!entry->valid) {
|
||
// 缺页处理
|
||
return PageFaultException;
|
||
}
|
||
|
||
// 4. 检查写权限
|
||
if (writing && entry->readOnly) {
|
||
return ReadOnlyException;
|
||
}
|
||
|
||
// 5. 计算物理地址
|
||
*physAddr = entry->physicalPage * PageSize + offset;
|
||
|
||
// 6. 更新引用位和修改位
|
||
entry->use = true;
|
||
if (writing) entry->dirty = true;
|
||
|
||
return NoException;
|
||
}
|
||
```
|
||
|
||
### 内存分配示例
|
||
|
||
```cpp
|
||
// AddrSpace/addrspace.cc - 进程地址空间初始化
|
||
// 为进程分配物理页框
|
||
void AddrSpace::InitRegisters() {
|
||
// 初始化页表
|
||
pageTable = new TranslationEntry[numPages];
|
||
for (int i = 0; i < numPages; i++) {
|
||
pageTable[i].virtualPage = i;
|
||
pageTable[i].physicalPage = bitMap->Find(); // 位示图分配
|
||
pageTable[i].valid = true;
|
||
pageTable[i].readOnly = false;
|
||
pageTable[i].use = false;
|
||
pageTable[i].dirty = false;
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 十二、小结
|
||
|
||
```mermaid
|
||
mindmap
|
||
root((分页存储管理))
|
||
碎片问题
|
||
内碎片(固定分区)
|
||
外碎片(动态分区)
|
||
根因:连续存放
|
||
分页思想
|
||
虚拟页VP
|
||
物理页框PF
|
||
等大划分
|
||
地址结构
|
||
VPN+VPO
|
||
PPN+PPO
|
||
页内偏移不变
|
||
页表
|
||
VPN→PPN映射
|
||
有效位/Dirty/Ref
|
||
每进程独立
|
||
地址变换
|
||
PTBR+VPN查页表
|
||
取PPN拼PPO
|
||
缺页中断处理
|
||
TLB快表
|
||
高速缓存页表项
|
||
命中率影响EAT
|
||
多级页表
|
||
页目录+页表
|
||
节省内存
|
||
倒转页表
|
||
按物理块号索引
|
||
全系统一张
|
||
```
|
||
|
||
---
|
||
|
||
## 思考题
|
||
|
||
1. **概念理解**: 为什么分页能消除外碎片但不能消除内碎片?内碎片平均浪费多少?
|
||
|
||
2. **计算题**: 某系统页面大小 4KB,虚拟地址 20 位,物理地址 18 位。
|
||
- 虚拟地址空间有多少页?
|
||
- 物理内存最大多少?
|
||
- 页表至少需要多少项?
|
||
|
||
3. **TLB计算**: 设 TLB 查找时间 5ns,内存访问时间 80ns,要求有效访问时间不超过 100ns,TLB 命中率至少为多少?
|
||
|
||
4. **多级页表**: 对于 64 位系统,为什么至少需要 3 级页表?
|
||
|
||
---
|
||
|
||
## 关联笔记
|
||
|
||
- [[13_存储管理基础]] — 存储器层次结构与地址空间基础
|
||
- [[15_段式存储管理]] — 分段式地址转换,段页式结合
|
||
- [[16_虚拟存储器]] — 基于分页的虚拟存储器实现
|
||
- [[11_处理机调度]] — 进程调度与缺页处理的关系
|
||
|
||
---
|
||
|
||
**上一讲**: [[13_存储管理基础]]
|
||
**下一讲**: [[15_段式存储管理]]
|