Files

705 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第4章 存储器
> 📖 本章介绍存储器的分类、工作原理和层次结构,是课程的重点和难点。
> 🎯 重点理解存储层次、主存组成、Cache和虚拟存储器
---
## 📋 本章目录
- [[#4.1 概述]]
- [[#4.2 主存储器]]
- [[#4.3 高速缓冲存储器]]
- [[#4.4 虚拟存储器]]
- [[#本章小结]]
---
## 4.1 概述
### 4.1.1 存储器分类
```mermaid
graph TB
A[存储器分类] --> B[按存储介质]
A --> C[按存取方式]
A --> D[按作用]
B --> B1[半导体存储器]
B --> B2[磁表面存储器]
B --> B3[光盘存储器]
C --> C1[随机存储器RAM]
C --> C2[只读存储器ROM]
C --> C3[串行访问存储器]
D --> D1[主存储器]
D --> D2[辅助存储器]
D --> D3[缓冲存储器Cache]
```
#### 按存储介质分类
| 类型 | 特点 | 示例 |
|------|------|------|
| 半导体存储器 | 体积小、功耗低、速度快、易失性 | SRAM、DRAM |
| 磁表面存储器 | 非易失、容量大、速度慢 | 磁盘、磁带 |
| 光盘存储器 | 非易失、容量大、可移动 | CD、DVD |
#### 按存取方式分类
| 类型 | 特点 | 应用 |
|------|------|------|
| **RAM** | 随机读写、存取时间与位置无关 | 主存 |
| **ROM** | 只读不写(或受限写入) | 固件、BIOS |
| **顺序存取** | 按物理顺序寻找(如磁带) | 磁带 |
| **直接存取** | 先直接定位区域,再顺序寻找(如磁盘) | 磁盘 |
#### RAM和ROM的细分
```mermaid
graph LR
RAM[随机存储器RAM] --> SRAM[静态RAM<br/>触发器原理]
RAM --> DRAM[动态RAM<br/>电容充放电]
ROM[只读存储器ROM] --> MROM[掩模ROM]
ROM --> PROM[可编程ROM]
ROM --> EPROM[可擦除PROM]
ROM --> EEPROM[电擦除PROM]
ROM --> Flash[闪速存储器]
```
### 4.1.2 存储器的层次结构
> [!important] 核心问题
> 速度、容量、价格三者不可兼得,需要通过层次结构解决矛盾。
#### 存储器性能指标关系
```mermaid
graph TB
subgraph "存储器层次结构"
REG["寄存器<br/>速度最快、容量最小、价格最高"] --> CACHE["Cache<br/>高速缓冲存储器"]
CACHE --> MEM["主存储器<br/>主存"]
MEM --> DISK["磁盘<br/>辅助存储器"]
DISK --> TAPE["磁带<br/>辅助存储器"]
end
style REG fill:#ff9999
style CACHE fill:#ffcc99
style MEM fill:#ffff99
style DISK fill:#99ff99
style TAPE fill:#9999ff
```
| 层次 | 速度 | 容量 | 价格 | 位置 |
|------|------|------|------|------|
| 寄存器 | 最快 | 最小 | 最高 | CPU内部 |
| Cache | 很快 | 小 | 高 | CPU内部/外部 |
| 主存 | 较快 | 中等 | 中等 | 主板 |
| 磁盘 | 慢 | 大 | 低 | 外部设备 |
| 磁带 | 最慢 | 最大 | 最低 | 外部设备 |
#### 两个存储层次
```mermaid
graph TB
subgraph "缓存-主存层次"
CPU1[CPU] <--> |"速度接近Cache"| CACHE[Cache]
CACHE <--> |"容量接近主存"| MEM1[主存]
end
subgraph "主存-辅存层次"
MEM2[主存] <--> |"速度接近主存"| DISK[辅存]
CPU2[CPU] -.-> |"不直接访问"| DISK
end
style CPU1 fill:#ff9999
style CPU2 fill:#ff9999
style CACHE fill:#ffcc99
style MEM1 fill:#ffff99
style MEM2 fill:#ffff99
style DISK fill:#99ff99
```
**缓存-主存层次**
- 解决CPU和主存**速度不匹配**问题
- 数据调动由**硬件**自动完成
- 对程序员**透明**
**主存-辅存层次**
- 解决存储系统**容量**问题
- 数据调动由**硬件+操作系统**完成
- 对程序员**透明**
---
## 4.2 主存储器
### 4.2.1 主存的基本组成
```mermaid
graph TB
subgraph "主存结构"
MAR[MAR<br/>地址寄存器] --> |"地址"| DEC[译码器]
DEC --> |"选择信号"| MEM[存储体]
MEM <--> |"数据"| MDR[MDR<br/>数据寄存器]
MDR <--> |"数据"| DBUS[数据总线]
MAR <--> |"地址"| ABUS[地址总线]
CTRL[控制电路] --> |"读写控制"| MEM
end
style MAR fill:#ff9999
style MDR fill:#99ccff
style MEM fill:#99ff99
style DEC fill:#ffcc99
```
**工作过程**
1. **读操作**CPU将地址送MAR → 地址总线 → 译码器选中单元 → 读出数据到MDR → 数据总线
2. **写操作**CPU将地址送MAR数据送MDR → 发写命令 → 数据写入选中单元
### 4.2.2 主存中存储单元地址的分配
#### 字节寻址与字寻址
```mermaid
graph TB
subgraph "IBM 37032位字长"
A1["地址0"] --> B1["字节0"]
A2["地址1"] --> B2["字节1"]
A3["地址2"] --> B3["字节2"]
A4["地址3"] --> B4["字节3"]
A5["地址4字地址"] --> B5["下一个字"]
end
subgraph "PDP-1116位字长"
C1["地址0字地址"] --> D1["字节0"]
C2["地址1"] --> D2["字节1"]
C3["地址2字地址"] --> D3["下一个字"]
end
```
> [!note] 地址表示
> - IBM 370字地址 = 高位字节地址4的倍数
> - PDP-11字地址 = 低位字节地址2的倍数
### 4.2.3 主存的技术指标
#### 1. 存储容量
$$存储容量 = 存储单元个数 \times 存储字长$$
**字节表示**
$$存储容量 = 存储单元个数 \times 存储字长 / 8$$
> [!example] 示例
> 24位地址线按字节寻址
> - 寻址范围:$2^{24} = 16M$ 个字节
> - 若字长32位按字寻址范围 = $16M / 4 = 4M$ 个字
#### 2. 存储速度
| 指标 | 定义 | 关系 |
|------|------|------|
| **存取时间** | 启动一次操作到完成的时间 | 读出时间或写入时间 |
| **存取周期** | 连续两次操作的最小间隔 | 存取周期 > 存取时间 |
| **存储器带宽** | 单位时间存取信息量 | 带宽 = 存储字长 / 存取周期 |
**提高带宽的措施**
1. 缩短存取周期
2. 增加存储字长
3. 增加存储体
### 4.2.4 半导体存储芯片
#### 芯片基本结构
```mermaid
graph LR
subgraph "存储芯片"
ADDR[地址线] --> DEC[译码驱动]
DEC --> MEM[存储矩阵]
MEM <--> RW[读/写电路]
RW <--> DATA[数据线]
CS[片选线] --> DEC
RW_CTRL[读写控制线] --> RW
end
```
**容量计算**
$$芯片容量 = 2^{地址线位数} \times 数据线位数$$
> [!example] 示例
> - 10根地址线4根数据线$2^{10} \times 4 = 4K$ 位
> - 14根地址线1根数据线$2^{14} \times 1 = 16K$ 位
#### 译码驱动方式
| 方式 | 特点 | 适用场景 |
|------|------|----------|
| **线选法** | 一根字线直接选中一个单元 | 容量小的芯片 |
| **重合法** | X、Y两个方向译码交叉点选中 | 大容量芯片 |
```mermaid
graph TB
subgraph "线选法16×1字节"
A1["A3A2A1A0 = 1111"] --> B1["第15根字线选中"]
B1 --> C1["8位数据读出"]
end
subgraph "重合法1K×1位"
A2["地址译码"] --> B2["X方向32根线"]
A2 --> C2["Y方向32根线"]
B2 --> D2["交叉点选中1位"]
C2 --> D2
end
```
### 4.2.5 随机存取存储器RAM
#### 静态RAMSRAM
**基本单元电路**6个MOS管组成的触发器
**特点**
- 用触发器原理寄存信息
- 速度快,不需要刷新
- 集成度低,功耗大
- 用于Cache
**典型芯片**Intel 21141K×4位
#### 动态RAMDRAM
**基本单元电路**1个MOS管 + 电容
**特点**
- 用电容充放电原理寄存信息
- 需要定期**刷新**
- 集成度高,功耗小
- 用于主存
**典型芯片**Intel 411616K×1位
**刷新方式**
| 方式 | 特点 | 效率 |
|------|------|------|
| 集中刷新 | 一段时间集中刷新所有行 | 有死区 |
| 分散刷新 | 每行刷新分散到各周期 | 无死区,效率低 |
| 异步刷新 | 各行刷新均匀分散 | 折中方案 |
#### SRAM vs DRAM 对比
| 特性 | SRAM | DRAM |
|------|------|------|
| 存储原理 | 触发器 | 电容 |
| 速度 | 快 | 较慢 |
| 集成度 | 低 | 高 |
| 功耗 | 大 | 小 |
| 刷新 | 不需要 | 需要 |
| 价格 | 高 | 低 |
| 应用 | Cache | 主存 |
### 4.2.6 只读存储器ROM
| 类型 | 特点 | 应用 |
|------|------|------|
| **MROM** | 厂家掩模制作,不可更改 | 批量生产 |
| **PROM** | 用户可编程一次 | 小批量 |
| **EPROM** | 紫外线擦除,可重复编程 | 开发调试 |
| **EEPROM** | 电擦除,可重复编程 | 参数存储 |
| **Flash** | 电擦除,速度快 | U盘、SSD |
### 4.2.7 存储器与CPU的连接
#### 存储器容量扩展
**三种扩展方式**
```mermaid
graph TB
subgraph "位扩展"
A1["芯片18位"] --> C1["组合16位"]
A2["芯片28位"] --> C1
end
subgraph "字扩展"
B1["芯片11K×8"] --> D1["组合2K×8"]
B2["芯片21K×8"] --> D1
end
subgraph "字位同时扩展"
E1["芯片1"] --> F1["组合"]
E2["芯片2"] --> F1
E3["芯片3"] --> F1
E4["芯片4"] --> F1
end
```
| 扩展方式 | 连接方法 | 应用场景 |
|----------|----------|----------|
| **位扩展** | 地址线、控制线并联,数据线串联 | 增加字长 |
| **字扩展** | 地址线、数据线、控制线并联,片选线用高位地址 | 增加字数 |
| **字位扩展** | 先位扩展,再字扩展 | 大容量存储器 |
#### 存储器与CPU连接示例
```mermaid
graph TB
subgraph "CPU"
MAR[MAR] --> |"地址"| ADDR[地址总线]
MDR[MDR] <--> |"数据"| DATA[数据总线]
CTRL[控制信号] --> |"读写"| RW[读写控制]
end
subgraph "存储器"
ADDR --> |"地址"| CHIP1[芯片1]
ADDR --> |"地址"| CHIP2[芯片2]
CHIP1 <--> |"数据"| DATA
CHIP2 <--> |"数据"| DATA
CS1[片选1] --> CHIP1
CS2[片选2] --> CHIP2
RW --> CHIP1
RW --> CHIP2
end
```
### 4.2.8 存储器的校验
#### 奇偶校验
**原理**增加1位校验位使数据中1的个数为奇数奇校验或偶数偶校验
**特点**
- 简单,只能检测奇数位错误
- 不能纠错
#### 海明码Hamming Code
**原理**:在数据位中插入多个校验位,通过校验位的组合定位错误位。
**校验位数r满足**$2^r \geq m + r + 1$m为数据位数
**特点**
- 可以检测并纠正1位错误
- 可以检测2位错误
> [!example] 示例
> 8位数据需要4位校验码
> - 总位数8 + 4 = 12位
> - 校验位位置1, 2, 4, 8
> - 可纠正1位错误
---
## 4.3 高速缓冲存储器Cache
### 4.3.1 Cache的基本原理
> [!important] 为什么需要Cache
> CPU速度远快于主存Cache作为中间缓冲解决速度不匹配问题。
```mermaid
graph LR
CPU[CPU] <--> |"速度匹配"| CACHE[Cache]
CACHE <--> |"容量大"| MEM[主存]
style CPU fill:#ff9999
style CACHE fill:#ffcc99
style MEM fill:#99ff99
```
**工作原理**
1. CPU访问数据时先查Cache
2. **命中**直接从Cache读取
3. **未命中**从主存读取同时调入Cache
### 4.3.2 Cache命中率
**命中率**
$$H = \frac{N_c}{N_c + N_m}$$
- $N_c$Cache访问次数
- $N_m$:主存访问次数
**平均访问时间**
$$T_a = HT_c + (1-H)T_m$$
**访问效率**
$$e = \frac{T_c}{T_a} = \frac{1}{H + (1-H)r}$$
其中 $r = T_m / T_c$主存与Cache访问时间之比
> [!example] 示例
> Cache命中率95%Cache访问时间10ns主存访问时间100ns
> $$T_a = 0.95 \times 10 + 0.05 \times 100 = 14.5ns$$
> $$e = \frac{10}{14.5} = 69\%$$
### 4.3.3 Cache地址映射
> [!info] 问题
> 主存块如何放入Cache需要地址映射。
#### 三种映射方式
##### 1. 直接映射Direct Mapping
**规则**每个主存块只能映射到Cache的固定行。
**映射公式**$i = j \mod m$
- iCache行号
- j主存块号
- mCache行数
```mermaid
graph LR
subgraph "直接映射"
M0[主存块0] --> C0[Cache行0]
M1[主存块1] --> C1[Cache行1]
Mm[主存块m] --> Cm[Cache行m]
Mm1[主存块m+1] --> C0
end
```
**地址结构**
| 标记Tag | Cache行号Index | 块内地址Offset |
|-------------|-------------------|-------------------|
**优点**:实现简单,查找速度快
**缺点**:灵活性差,命中率低
##### 2. 全相联映射Fully Associative Mapping
**规则**主存块可以映射到Cache的任意行。
```mermaid
graph LR
subgraph "全相联映射"
M0[主存块0] --> |"任意行"| CACHE[Cache]
M1[主存块1] --> |"任意行"| CACHE
Mn[主存块n] --> |"任意行"| CACHE
end
```
**地址结构**
| 标记Tag | 块内地址Offset |
|-------------|-------------------|
**优点**:灵活性好,命中率高
**缺点**:查找速度慢,硬件成本高
##### 3. 组相联映射Set Associative Mapping
**规则**将Cache分组主存块映射到固定组组内任意行。
**映射公式**$q = j \mod u$
- qCache组号
- j主存块号
- uCache组数
```mermaid
graph LR
subgraph "组相联映射"
M0[主存块0] --> G0[Cache组0]
M1[主存块1] --> G1[Cache组1]
Mu[主存块u] --> Gu[Cache组u]
Mu1[主存块u+1] --> G0
end
```
**地址结构**
| 标记Tag | 组号Index | 块内地址Offset |
|-------------|--------------|-------------------|
**优点**:折中方案,兼顾速度和命中率
**应用**现代Cache常用2路、4路、8路组相联
#### 三种映射方式对比
| 方式 | 映射规则 | 灵活性 | 命中率 | 硬件复杂度 |
|------|----------|--------|--------|------------|
| 直接映射 | 固定行 | 差 | 低 | 简单 |
| 全相联映射 | 任意行 | 好 | 高 | 复杂 |
| 组相联映射 | 固定组,任意行 | 中 | 中 | 中等 |
### 4.3.4 Cache替换算法
> [!info] 问题
> Cache满时新块调入需要替换旧块如何选择
#### 常用替换算法
| 算法 | 原则 | 优点 | 缺点 |
|------|------|------|------|
| **FIFO** | 先进先出 | 实现简单 | 不考虑访问频率 |
| **LRU** | 最近最少使用 | 命中率高 | 实现复杂 |
| **LFU** | 最不经常使用 | 考虑频率 | 需要计数器 |
| **随机替换** | 随机选择 | 实现简单 | 命中率不稳定 |
**LRU算法实现**
- 为每行设置计数器
- 每次访问命中行计数器清零其他行加1
- 替换计数器值最大的行
### 4.3.5 Cache写策略
> [!info] 问题
> Cache数据修改后如何与主存保持一致
#### 写策略
| 策略 | 方法 | 优点 | 缺点 |
|------|------|------|------|
| **写直达** | 同时写Cache和主存 | 数据一致性好 | 速度慢 |
| **写回法** | 只写Cache替换时写回主存 | 速度快 | 数据可能不一致 |
```mermaid
graph TB
subgraph "写直达"
CPU1[CPU] --> |"写"| CACHE1[Cache]
CPU1 --> |"同时写"| MEM1[主存]
end
subgraph "写回法"
CPU2[CPU] --> |"写"| CACHE2[Cache]
CACHE2 --> |"替换时写回"| MEM2[主存]
end
```
### 4.3.6 Cache性能分析
**加速比**
$$加速比 = \frac{T_m}{T_a} = \frac{r}{1 + (r-1)H}$$
**Cache容量选择**
- 太小:命中率低
- 太大:成本高,速度可能下降
- 通常几十KB到几MB
---
## 4.4 虚拟存储器
### 4.4.1 虚拟存储器的概念
> [!info] 定义
> 虚拟存储器是一个逻辑模型,程序员看到的地址空间远大于实际主存。
**特点**
- **虚拟地址**(逻辑地址):程序员使用的地址
- **物理地址**(实地址):主存实际地址
- 地址转换由硬件和OS自动完成
```mermaid
graph TB
subgraph "虚拟存储器"
VA[虚拟地址空间<br/>很大] --> |"地址转换"| PA[物理地址空间<br/>较小]
PA --> MEM[主存]
MEM --> DISK[辅存]
end
```
### 4.4.2 页式虚拟存储器
**基本思想**
- 虚拟地址空间划分为固定大小的**页**
- 主存划分为相同大小的**页框**
- 通过**页表**建立映射关系
**地址结构**
| 虚页号 | 页内地址 |
|--------|----------|
**页表项**
| 虚页号 | 实页号 | 有效位 | 修改位 |
|--------|--------|--------|--------|
**地址转换过程**
1. 从虚拟地址取出虚页号
2. 查页表得到实页号
3. 实页号 + 页内地址 = 物理地址
### 4.4.3 TLB快表
> [!info] 问题
> 页表在主存中,每次访问都要查页表,速度慢。
**解决方案**在CPU中设置TLBTranslation Lookaside Buffer
**特点**
- 高速小容量存储器
- 存放最近使用的页表项
- 命中率通常 > 99%
**访问流程**
1. 先查TLB
2. **TLB命中**:直接得到物理地址(快)
3. **TLB未命中**查页表更新TLB
---
## 📝 本章小结
### 核心概念
1. **存储层次**:寄存器 → Cache → 主存 → 辅存
2. **主存组成**:存储体 + MAR + MDR + 译码驱动 + 读写电路
3. **RAM分类**SRAM用于Cache、DRAM用于主存
4. **Cache映射**:直接映射、全相联映射、组相联映射
5. **虚拟存储器**:虚拟地址 → 物理地址的转换
### 关键公式
- **存储容量** = 存储单元个数 × 存储字长
- **Cache命中率** $H = N_c / (N_c + N_m)$
- **平均访问时间** $T_a = HT_c + (1-H)T_m$
- **访问效率** $e = T_c / T_a$
### 重点图示
> [!summary] 必须掌握的图
> 1. 存储器层次结构图
> 2. 主存基本组成框图
> 3. Cache三种映射方式示意图
> 4. Cache访问流程图
---
## 🧪 自测练习
### 概念题
1. 说明存储器层次结构的必要性。
2. 比较SRAM和DRAM的特点。
3. 解释Cache三种映射方式的区别。
### 计算题
1. 某系统Cache命中率90%Cache访问时间20ns主存访问时间200ns求平均访问时间和访问效率。
2. 24位地址线按字节寻址存储字长32位求存储容量。
### 分析题
1. 设计一个16K×8位的存储器使用4K×4位的芯片。
2. 说明Cache写策略的选择依据。
---
## 🔗 相关链接
- [[03_系统总线]] - 上一章
- [[05_输入输出系统]] - 下一章
- [[08_CPU结构与功能]] - CPU访问存储器
- [[06_运算方法]] - 数据表示
---
*本章难度:⭐⭐⭐⭐⭐ 困难*
*重要程度:⭐⭐⭐⭐⭐ 核心重点*