存储器系统:主存、Cache、虚拟存储器与外部存储层次。
3.1 存储器概述
3.1.1 存储器的分类
1. 按存储元件分类
- 半导体存储器:用半导体器件构成。
- 磁表面存储器:如磁盘、磁带。
- 光介质存储器:光盘存储器。
2. 按存取方式分类
| 类型 |
特点 |
示例 |
| 随机存取存储器(RAM) |
按地址访问,访问时间固定且相等 |
Cache、主存 |
| 顺序存储存储器(SAM) |
信息按顺序存放和读出,存取时间取决于位置 |
磁带存储器 |
| 直接存取存储器(DAM) |
先随机选取区域,再顺序访问 |
磁盘存储器 |
| 相联存储器(AM) |
按内容检索,也称按内容访问存储器(CAM) |
快表(TLB) |
3. 按信息的可更改性分类
- 读写存储器:既能读又能写。
- **只读存储器(ROM)**:通常只读不写,某些情况下可重写。
4. 按断电后信息的可保存性分类
- 非易失性存储器:断电后信息保持(ROM、磁表面、光存储器)。
- 易失性存储器:断电后信息丢失(RAM、Cache)。
5. 按功能分类
| 类型 |
特点 |
速度 |
容量 |
| 高速缓冲存储器(Cache) |
位于主存和CPU之间,存放当前常用指令和数据 |
最快 |
最小 |
| 主存储器(主存) |
CPU可直接随机访问,存放当前运行的程序和数据 |
较快 |
较小 |
| 辅助存储器(辅存) |
存放暂时不用的程序和数据,需调入主存后才能访问 |
最慢 |
最大 |
3.1.2 存储器的性能指标
| 指标 |
定义 |
| 存储容量 |
存储字数 × 存储字长 |
| 单位成本 |
总成本 / 总容量 |
| 存取时间($T_a$) |
启动一次存储器操作到完成所需时间 |
| 存取周期($T_m$) |
存储器连续读写操作允许的最短间隔时间,$T_m = T_a +$ 附加时间 |
| 主存带宽(B) |
数据传输速率,单位:字/秒、B/s、b/s |
3.1.3 层次化存储器的基本结构
- 目的:兼顾大容量、高速度、低成本。
- 层次结构:
- Cache-主存层:解决速度不匹配问题,由硬件自动完成,对所有程序员透明。
- 主存-辅存层:解决容量问题,由硬件和OS共同完成,对应用程序员透明。
3.2 主存储器
3.2.1 SRAM和DRAM
| 类型 |
存储元 |
特点 |
用途 |
| SRAM |
双稳态触发器 |
非破坏性读出,不需刷新,速度快,集成度低,价格高 |
Cache |
| DRAM |
晶体管 |
破坏性读出,需定时刷新,速度慢,集成度高,价格低 |
主存 |
DRAM的刷新
- 刷新单位:行。
- 刷新周期:通常2ms。
- 刷新方式:
- 集中刷新:固定时间刷新所有行,存在“死区”(访存死区)。
- 分散刷新:每个工作周期分两部分(读写+刷新),无死区,但存取周期延长。
- 异步刷新:结合两者,刷新周期内均匀刷新各行。
DRAM地址引脚复用
- 行地址和列地址分两次通过相同引脚输入,减少引脚数。
3.2.2 只读存储器(ROM)
| 类型 |
特点 |
| MROM |
掩模式,内容在芯片生产时写入,不可改 |
| PROM |
一次可编程,用户写入一次,不可改 |
| EPROM |
可擦除可编程,多次改写,但写入次数有限 |
| Flash |
可长期保存,快速擦除和重写 |
| SSD |
固态硬盘,由控制单元和Flash组成 |
3.2.3 主存储器的基本组成
- 存储体:存储单元的集合。
- 地址译码:一维译码(字线多)、二维译码(行+列译码)。
- 片选控制信号:选中要访问的芯片。
- 读写控制信号:控制读/写操作。
CPU访存过程:
- CPU将地址送MAR → 地址线 → 主存地址寄存器 → 地址译码。
- CPU将读写信号送控制线 → 主存读写控制电路。
- 读操作:主存读出数据 → 数据线 → MDR。
- 写操作:CPU将数据送MDR → 数据线 → 主存写入选中单元。
3.2.4 多模块存储器
1. 连续编址方式
- 高位为模块号,低位为模块内地址。
- 模块内地址连续,模块间串行访问,不能提高吞吐率。
2. 交叉编址方式
- 低位为模块号,高位为模块内地址。
- 模块间交叉编址,可并行访问。
- 轮流启动:每隔 $1/m$ 个存储周期启动一个模块,吞吐率提高 $m$ 倍。
- 同时启动:所有模块同时启动,一次提供 $m \times$ 字长数据。
3.3 主存储器和CPU的连接
3.3.1 位扩展
- 目的:增加存储字长(位数)。
- 连接方式:地址线、读写控制线、片选线对应相连,数据线单独引出。
3.3.2 字扩展
- 目的:增加存储容量(字数)。
- 连接方式:地址线低位相连,片选信号由高位地址经译码器产生。
3.3.3 字位同时扩展
- 目的:既扩展容量又扩展位数。
- 连接方式:位扩展的芯片作为一组,组内位扩展,组间字扩展。
3.4 外部存储器
3.4.1 磁盘存储器
组成
- 磁盘驱动器:驱动磁盘转动,进行读写。
- 磁盘控制器:主机与磁盘驱动器的接口。
- 盘片:存储介质。
存储区域
- 记录面(磁头数):盘片数量 × 2。
- 磁道:记录面上的同心圆。
- 柱面:不同记录面相同位置的磁道集合。
- 扇区(块):磁盘读写的最小单位。
性能指标
| 指标 |
定义 |
| 记录密度 |
道密度(径向单位长度磁道数)、位密度(磁道单位长度位数) |
| 磁盘容量 |
格式化容量 = 记录面数 × 柱面数 × 每道扇区数 × 扇区容量 |
| 存取时间 |
寻道时间 + 旋转延迟时间 + 传输时间(通常取平均值) |
| 数据传输速率 |
单位时间传送的数据量 |
RAID(独立冗余磁盘阵列)
| 级别 |
特点 |
| RAID0 |
条带化,无冗余,提高速度,无容错 |
| RAID1 |
镜像,容量减半,高可靠性 |
| RAID5 |
奇偶校验,分布式校验块,兼顾性能与容错 |
3.4.2 固态硬盘(SSD)
- 组成:闪存芯片 + 闪存翻译层(控制器)。
- 结构:块(Block)→ 页(Page),读写以页为单位。
- 写操作:若页非空,需将所在块有效页复制到新块,再写入,再擦除原块。
- 磨损均衡:动态磨损均衡(写时选较新块)、静态磨损均衡(分配老块存静态数据)。
3.5 高速缓冲存储器(Cache)
3.5.1 程序访问的局部性原理
- 时间局部性:当前使用的信息近期可能再次使用。
- 空间局部性:近期要用的信息与当前信息在空间上邻近。
3.5.2 Cache的基本工作原理
3.5.3 Cache和主存的映射方式
1. 直接映射
- 映射关系:Cache行号 = 主存块号 mod Cache行数。
- 主存地址格式:| 标记(t) | 行号(c) | 块内地址 |
- 特点:简单,但冲突率高,命中率低。
2. 全相联映射
- 映射关系:主存块可映射到任意Cache行。
- 主存地址格式:| 标记 | 块内地址 |
- 特点:冲突率低,命中率高,但硬件开销大(需比较器)。
3. 组相联映射
- 映射关系:组间直接映射,组内全相联映射。
- 主存地址格式:| 标记(t) | 组号(k) | 块内地址 |
- 特点:折中方案,$r$路组相联即每组$r$行。
| 映射方式 |
命中率 |
硬件开销 |
冲突率 |
| 直接映射 |
最低 |
最小 |
最高 |
| 全相联映射 |
最高 |
最大 |
最低 |
| 组相联映射 |
中等 |
中等 |
中等 |
3.5.4 Cache中主存块的替换算法
| 算法 |
特点 |
| 随机算法 |
随机替换,无局部性依据 |
| 先进先出(FIFO) |
替换最早调入的行,无局部性依据 |
| 最近最少使用(LRU) |
替换最久未访问的行,利用局部性原理,命中率高 |
LRU计数器规则($2^k$路):
- 命中:被访问行计数器清零,比其低的加1,其余不变。
- 未命中且有空间:新行计数器=0,其余加1。
- 未命中且无空间:淘汰计数值最大行,新行计数器=0,其余加1。
3.5.5 Cache的一致性问题
写命中时
| 策略 |
做法 |
优缺点 |
| 全写法 |
同时写入Cache和主存 |
实现简单,一致性好,但访存次数多 |
| 回写法 |
只写Cache,替换时写回主存 |
访存次数少,需设脏位,存在不一致隐患 |
写不命中时
| 策略 |
做法 |
| 写分配法 |
更新主存,将块调入Cache |
| 非写分配法 |
只更新主存,不调入Cache |
典型组合:全写法 + 非写分配法;回写法 + 写分配法。
3.5.6 指令Cache和数据Cache分离
- 优点:避免取指令与取数据的资源冲突,利用不同局部性优化性能。
3.5.7 Cache容量计算
- Cache容量 = 数据区容量 + 标记区容量
- 数据区容量 = 块大小 × 块数
- 标记区容量 = (标记 + 有效位 + 脏位 + 替换控制位) × 块数
- 标记位位数:
- 直接映射:$n - k - p$($n$:地址位数,$k$:行号位数,$p$:块内地址位数)
- 全相联映射:$n - p$
- 组相联映射:$n - (k-r) - p$($r$:组内行数指数)
3.6 虚拟存储器
3.6.1 基本概念
- 目的:将主存和辅存统一编址,形成大容量地址空间。
- 逻辑地址(虚地址):用户编程使用的地址。
- 物理地址(实地址):实际主存单元地址。
- 特点:用户看来拥有辅存的容量和主存的速度。
3.6.2 页式虚拟存储器
页表
- 页表项字段:
- 装入位(有效位):页面是否在主存。
- 修改位(脏位):页面是否被修改(回写用)。
- 使用位(替换控制位):用于替换算法。
- 存放位置:物理页号(在主存时)或磁盘地址(不在主存时)。
地址转换
- 虚地址:| 虚页号 | 页内偏移 |
- 物理地址:| 物理页号 | 页内偏移 |
- 转换过程:页表基址寄存器 → 页表 → 虚页号索引 → 页表项 → 物理页号 + 页内偏移
快表(TLB)
- 将活跃的页表项复制到高速缓存(SRAM),采用全相联或组相联。
- 作用:减少访存次数,加快地址转换。
多级存储系统(TLB + Cache)的CPU访存过程
TLB、Page、Cache三种缺失情况:
| 序号 |
TLB |
Page |
Cache |
说明 |
| 1 |
命中 |
命中 |
命中 |
信息在Cache中 |
| 2 |
命中 |
命中 |
缺失 |
信息在主存,不在Cache |
| 3 |
缺失 |
命中 |
命中 |
信息在主存和Cache中 |
| 4 |
缺失 |
命中 |
缺失 |
信息在主存,需访存两次 |
| 5 |
缺失 |
缺失 |
缺失 |
缺页,需访问磁盘 |
3.6.3 段式虚拟存储器
- 段:按程序逻辑结构划分,长度可变。
- 虚地址:| 段号 | 段内地址 |
- 段表:记录段起点、段长、装入位等。
- 优点:逻辑独立,易于管理、保护。
- 缺点:段间碎片,空间浪费。
3.6.4 段页式虚拟存储器
- 先按逻辑结构分段,每段再分页。
- 虚地址:| 段号 | 段内页号 | 页内地址 |
- 转换过程:段表 → 页表 → 物理页号 + 页内地址。
3.6.5 虚拟存储器与Cache的比较
| 对比项 |
Cache |
虚拟存储器 |
| 主要目的 |
解决速度问题 |
解决容量问题 |
| 实现方式 |
硬件 |
硬件 + OS |
| 透明性 |
对所有程序员透明 |
对应用程序员透明,对系统程序员不透明 |
| 缺失代价 |
访问主存 |
访问磁盘(代价更大) |
| 数据流 |
主存 → Cache → CPU |
磁盘 → 主存 → CPU |
3.6.6 数据的对齐存储
边界对齐
- 要求存储地址是数据自身大小的整数倍。
- 优点:一次访存即可取出数据(空间换时间)。
结构体的边界对齐
- 对齐规则:
- 每个成员按自身类型大小对齐(char:1, short:2, int:4)。
- 结构体长度为最大成员对齐值的整数倍。
示例(32位环境):
1 2 3 4 5 6 7 8 9 10 11
| struct A { int a; char b; short c; };
struct B { char b; int a; short c; };
|