首页 / 第2章 存储器系统

存储器系统

存储器层次结构、Cache映射、虚拟内存、页面置换算法、DRAM芯片、磁盘与SSD

1. 存储器概述

存储器是计算机系统中的记忆设备,用来存放程序和数据。现代计算机系统采用多层次的存储器结构,以解决速度、容量和价格之间的矛盾。

1.1 存储器分类

分类方式 类型 特点
按存储介质 半导体存储器 速度快、体积小、功耗低(内存、Cache)
磁表面存储器 容量大、价格低、速度慢(磁盘、磁带)
按存取方式 随机存取 RAM 可读可写、断电丢失(DRAM、SRAM)
只读存取 ROM 只读不写、断电保存(ROM、PROM、EPROM)
按作用 主存储器 CPU可直接访问,存放运行中程序和数据
辅助存储器 CPU不可直接访问,存放大量数据(磁盘)

1.2 SRAM与DRAM

RAM(随机存取存储器)分为静态RAM(SRAM)和动态RAM(DRAM),二者工作原理不同,特点各异。

特性 SRAM(静态) DRAM(动态)
存储原理 双稳态触发器(6管) 电容存储电荷(1管+1电容)
是否需要刷新 不需要 需要(2ms内刷新一次)
速度 较慢
集成度
功耗
价格 便宜
用途 Cache 主存

DRAM刷新方式

集中刷新

在2ms内集中一段时间对所有行刷新
缺点:有死区时间,CPU不能访存

分散刷新

把刷新分散到每个存取周期中
缺点:系统速度降低,没有死区

异步刷新

每隔一定时间刷新一行
优点:死区短,效率高,最常用

1.3 只读存储器ROM与Flash

ROM在正常工作时只能读出不能写入,断电后数据不丢失,常用于存放固定程序和数据。

类型 写入方式 特点
MROM 生产时厂家写入 固定不可改,批量生产成本低
PROM 用户一次写入 只能写一次,不可擦除
EPROM 紫外线擦除后写入 可多次擦写,需紫外线照射
EEPROM 电擦除写入 电可擦除,可按字节擦写
Flash Memory 电擦除写入 速度快、容量大、价格低,U盘、SSD
💡
易混淆点
RAM断电丢失数据(易失性),ROM断电不丢失(非易失性)。
注意:RAM是随机存取(任意地址访问时间相同),不是"只写",RAM可读可写。

1.2 DRAM芯片与内存条

DRAM芯片是构成主存储器的核心元件,多个DRAM芯片组合形成内存条(内存模块)。

DRAM芯片内部结构

DRAM芯片内部采用行列地址复用技术,通过地址线分时传送行地址和列地址。

DRAM芯片内部结构示意图
🔲
存储矩阵
n×n的存储单元矩阵
每个单元为1位数据
按行列组织
📍
地址缓冲器
接收外部地址信号
RAS锁存行地址
CAS锁存列地址
行/列译码器
将地址转换为选择信号
选中特定行和列
定位存储单元
🔄
读写控制电路
数据输入/输出缓冲
读写信号控制
刷新控制逻辑
地址复用技术:DRAM芯片地址线数量减少一半(如4M×1位芯片只需12根地址线而非24根),RAS(行地址选通)和CAS(列地址选通)分时控制。

内存条的组成

IC1
IC2
IC3
IC4
IC5
IC6
IC7
IC8
DRAM芯片
定位缺口(防误插)
PCB电路板
内存条类型 引脚数 位宽 特点
SIMM 30/72 单面 早期内存条,已淘汰
DIMM 168/184/240/288 双面独立 现代主流内存条(DDR系列)
RIMM 184 双面 RDRAM专用,已淘汰

内存条工作原理

  • 位扩展:8个4M×1位芯片组成4M×8位内存条,每个芯片存储同一地址的不同位
  • 字扩展:多个内存条插槽实现更大的存储容量,高位地址译码选中不同插槽
  • 访问过程:CPU发送地址 → 内存控制器解码 → RAS/CAS信号 → 选中芯片的指定单元 → 数据传输
DRAM芯片容量计算:
容量 = 行数 × 列数 × 位宽
地址线数量 = log₂(行数) + log₂(列数)(复用后)
例:4M×1位芯片 = 2048行 × 2048列,需12根地址线
📌
DDR内存技术
DDR(Double Data Rate)在时钟上升沿和下降沿各传输一次数据,理论带宽翻倍。
DDR4常见频率:2133/2400/3200MHz,DDR5可达4800MHz以上。

2. 存储器层次结构

为了解决存储器速度、容量和价格三者之间的矛盾,计算机系统采用多级存储器层次结构。

存储器层次结构
寄存器
CPU内部,最快,容量最小(几KB)
~1ns
💾
高速缓存 Cache
SRAM构成,速度快,容量较小(几MB)
~2ns
📦
主存储器
DRAM构成,容量较大(几GB)
~10ns
🖴
辅助存储器
磁盘/SSD,容量大,速度慢(几TB)
~10ms
局部性原理:时间局部性(刚访问过的内容可能很快再次访问)和空间局部性(访问的内容附近的内容也可能被访问)是Cache和虚拟存储器的理论基础。
📌
两个层次 Cache-主存层次:解决速度问题,由硬件实现,对程序员透明
主存-辅存层次(虚拟存储):解决容量问题,由硬件和操作系统共同实现

3. 主存与CPU的连接

主存和CPU之间通过地址总线、数据总线和控制总线连接。当存储芯片容量不足时,需要进行扩展。

3.1 连接的基本概念

  • 地址总线:传输地址信息,由CPU发往主存,决定访存单元的地址
  • 数据总线:传输数据,双向传输,宽度等于机器字长
  • 控制总线:传输控制信号,如读/写命令、片选信号等

3.2 存储器容量扩展

当单个存储芯片容量不满足需求时,需要进行扩展。有三种基本扩展方式:

📏 位扩展

增加存储字长
所有芯片地址线并联
数据线分别连接
片选信号同时有效

📐 字扩展

增加存储字的数量
数据线并联
地址线低位并联
高位译码产生片选

📊 字位同时扩展

同时增加字数和字长
先位扩展成一组
再字扩展多组
实际中最常用

芯片数量计算:
总容量 = 字数 × 字长(位)
芯片数 = (总字数 / 芯片字数) × (总字长 / 芯片字长)
片选译码器输入位数 = log₂(总字数 / 芯片字数)

地址译码方式

  • 线选法:用高位地址线直接做片选信号,电路简单但地址不连续,浪费地址空间
  • 译码器译码(译码法):高位地址输入译码器,译码输出做片选,地址连续,常用74LS138等

4. 双口RAM与多模块存储器

为了提高主存的访问速度和带宽,可以采用双口RAM或多模块存储器。

4.1 双端口RAM

双端口RAM有两个独立的端口,允许两个CPU或设备同时访问同一个存储体。

  • 两个端口各有独立的地址线、数据线和控制线
  • 可以同时进行读操作,但同时写或一读一写同一地址时会发生冲突
  • 通过设置"忙"信号解决冲突,由片上仲裁逻辑决定哪个端口优先

4.2 多模块存储器

将主存分成多个存储模块,每个模块有独立的地址寄存器和数据寄存器,可以并行工作。

高位交叉编址(顺序方式)

高位地址表示模块号,低位表示模块内地址
同一模块内地址连续
特点:存储器模块串行工作,不能提高访问速度
优点:模块扩充方便,可靠性高

低位交叉编址(交叉方式)

低位地址表示模块号,高位表示模块内地址
连续地址分布在不同模块
特点:流水线方式并行工作,提高访问带宽
优点:连续地址访问速度快,m模块理论上m倍

低位交叉存储器带宽:
m个模块,存取周期为T,总线传输周期为r
连续读取m个字的时间 = T + (m-1) × r
当r = T/m时,流水线方式可接近m倍带宽

5. Cache 基本原理

高速缓冲存储器(Cache)位于CPU和主存之间,用来存放当前最常用的程序和数据,以减少CPU的访存时间。

3.1 Cache工作原理

当CPU要访问主存时,首先检查Cache中是否有所需的数据:

  • 命中(Hit):数据在Cache中,直接从Cache读取,速度快
  • 不命中(Miss):数据不在Cache中,需要从主存读取,并将该数据所在块调入Cache
Ta = h × Tc + (1 - h) × (Tc + Tm)
Ta:平均访存时间    h:命中率    Tc:Cache访问时间    Tm:主存访问时间

4. Cache 映射方式

Cache映射是指主存块和Cache行之间的对应关系。三种常用映射方式:直接映射、全相联映射、组相联映射。

4.1 三种映射方式对比演示

选择不同的映射方式,查看地址如何映射到Cache中。点击"下一步"逐步执行访存序列。

Cache映射方式交互演示
访问序列: 0/8
主存地址结构:
标记位 Tag
--
索引位 Index
--
块内偏移 Offset
--
主存块 (8块)
映射过程
Cache (4行)
0
命中次数
0
不命中次数
0%
命中率
直接映射:主存块 i 只能映射到 Cache 第 i mod 4 行。地址结构:标记位(1位) + 索引位(2位) + 块内偏移。优点是简单,缺点是冲突率高。

4.2 三种映射方式对比

映射方式 映射规则 优点 缺点 适用场景
直接映射 i mod C 硬件简单、成本低 冲突率高、命中率低 大容量Cache
全相联 任意行 冲突率低、命中率高 比较器多、成本高 小容量Cache
组相联 组间直接、组内全相联 折中方案、性价平衡 复杂度中等 最常用

7. Cache 替换算法

当Cache不命中且Cache已满时,需要选择一行替换出去。常用的替换算法有以下几种。

Cache替换算法交互动画
访问: 0/10
访问序列:
Cache 行 (4行):
统计:
命中: 0
缺失: 0
命中率: 0%
点击"下一步"开始演示

7.2 替换算法对比

算法 思想 命中率 实现难度 特点
随机法 RAND 随机选择一行替换 较低 最简单 完全随机,无策略依据
先进先出 FIFO 替换最早进入的行 较低 简单 可能出现Belady异常
最近最少用 LRU 替换最久未使用的行 较高 较复杂 基于局部性原理,最常用
最不经常用 LFU 替换使用次数最少的行 较高 中等 需要计数器记录访问次数
⚠️
Belady异常
FIFO算法可能出现:分配的Cache页数增加,命中率反而降低的异常现象。LRU算法不会出现Belady异常,因为它是堆栈类算法。

7.3 Cache写策略

写操作时如何保持Cache和主存的数据一致性,有两种基本策略:

📝 全写法(写直达)

写Cache时同时写主存
优点:一致性好,实现简单
缺点:写操作速度慢,增加主存写次数
常配合写缓冲(Write Buffer)使用

💾 写回法

只写Cache,不写主存
替换时才把修改过的行写回主存
优点:写操作速度快,减少主存写次数
缺点:需要修改位(脏位),一致性稍差

写不命中时的处理: 写分配法(加载分配):先把所在块调入Cache再写; 非写分配法(写不分配):直接写主存,不调入Cache。 通常全写法配合非写分配,写回法配合写分配。

8. Cache 性能分析

8.1 命中率与平均访存时间

命中率 h = 命中次数 / 总访问次数
平均访存时间 Ta = 命中时间 + 不命中率 × 不命中开销

5.2 不命中的三种类型(3C模型)

  • 强制性不命中(Compulsory):第一次访问某个块时必然不命中,也称冷启动不命中
  • 容量不命中(Capacity):Cache容量太小,装不下程序执行所需的全部块
  • 冲突不命中(Conflict):太多块映射到同一Cache组/行,导致频繁替换
💡
提高Cache命中率的方法 增大Cache容量、提高相联度、增加块大小(但过大可能增加不命中开销)、采用多级Cache、优化编译

5.3 Cache写策略

策略 写命中时 写不命中时 特点
写直达 (Write Through) 同时写Cache和主存 写分配法 / 非写分配法 简单可靠,但写操作慢
写回法 (Write Back) 只写Cache,块被替换时才写回主存 写分配法(取入Cache再写) 写速度快,需设置修改位

9. 虚拟存储器

虚拟存储器是主存-辅存层次的实现,它使得程序可以使用比实际主存大得多的逻辑地址空间。

9.1 页式虚拟存储器

页式虚拟存储器将虚拟地址空间和物理地址空间划分为大小相等的页,页面大小固定(如4KB)。虚拟页和物理页之间通过页表建立映射关系。

基本概念

  • 虚拟地址(逻辑地址):程序员编程使用的地址,由编译程序生成
  • 物理地址:主存的实际地址,是地址转换后的结果
  • 地址重定位/映射:将虚拟地址转换为物理地址的过程
  • 页表:记录虚拟页号与物理页号的对应关系

页表结构

字段 说明 作用
页号 虚拟页的编号 作为页表索引,定位页表项
页框号/物理页号 该页在主存中的页框号 地址转换时组成物理地址高位
存在位 该页是否在主存中 缺页判断
修改位(脏位) 该页是否被修改过 决定替换时是否写回磁盘
访问位 该页是否被访问过 页面置换算法使用
访问权限 读/写/执行权限 存储保护
页式地址结构:
虚拟地址 = 虚拟页号(P位)+ 页内偏移(D位)
物理地址 = 页框号 + 页内偏移
页大小 = 2^D 字节(如D=12,页大小=4KB)

TLB(快表)

为了加快地址变换速度,在Cache中设置一个专门的高速缓冲存储器,存放最近常用的页表项,称为转换检测缓冲器(TLB)。

TLB与页表工作过程
就绪
地址转换过程:CPU发出虚拟地址 → 查询TLB → TLB命中直接得物理页号 → TLB不命中则查页表 → 更新TLB → 访问主存

9.2 段式虚拟存储器

段式虚拟存储器将程序按逻辑结构划分成若干段,每段有段名和段长,段长可变。段是程序的逻辑单位,如代码段、数据段、堆栈段等。

段表结构

每个进程有一个段表,记录各段的信息。段表项包含:

字段 说明 作用
段号 段的编号 作为段表索引,定位段表项
段基址 该段在主存中的起始地址 地址转换时计算物理地址
段长 段的长度(字节数) 判断地址是否越界
存在位 该段是否在主存中 缺段判断
访问权限 读/写/执行权限 存储保护

地址转换过程

段式虚拟存储器地址转换
就绪
段式地址转换:虚拟地址 = 段号 + 段内偏移 → 查段表得段基址 → 段基址 + 段内偏移 = 物理地址(需检查段内偏移 ≤ 段长)

段的共享与保护

🔄 段的共享

多个进程的段表项指向同一物理段
适合共享代码段、公共数据
只读段(如库函数)可安全共享
修改时需采用写时复制(COW)

🛡️ 段的保护

越界检查:段内偏移 > 段长则越界
存取控制:读/写/执行权限检查
环级保护:内环可访问外环,反之不行
特权级保护:用户态/内核态访问限制

💡
段式存储的特点
优点:段是逻辑单位,便于共享、保护、动态增长;符合程序逻辑结构
缺点:段长不等,主存分配麻烦,易产生外部碎片;段表开销较大

9.3 段页式虚拟存储器

段页式虚拟存储器结合了段式和页式的优点,是目前大多数计算机系统采用的虚拟存储管理方式。

基本原理

  • 分段:按程序逻辑结构将用户程序分成若干段,每段有段名
  • 分页:每段再分成若干页,页面大小固定
  • 两级查找:先查段表找到页表起始地址,再查页表找到物理页框

段表和页表结构

包含字段 作用
段表 段号 段表索引,定位段表项
页表始址 该段页表在主存中的起始地址
页表长度 该段包含的页面数
存在位、访问权限 段级保护和存在性判断
页表 页号 页表索引,定位页表项
页框号/物理页号 该页在主存中的页框号
存在位、修改位 缺页判断、写回判断
访问权限 页级保护(读/写/执行)

地址转换过程

段页式虚拟存储器地址转换
就绪
段页式地址转换:虚拟地址 = 段号 + 页号 + 页内偏移 → 查段表得页表始址 → 查页表得页框号 → 页框号 + 页内偏移 = 物理地址
段页式地址结构:
虚拟地址 = 段号(S位)+ 页号(P位)+ 页内偏移(D位)
物理地址 = 页框号 + 页内偏移
访存次数:段表(1次)+ 页表(1次)+ 数据访问(1次)= 3次
使用TLB可减少访存次数

9.4 三种虚拟存储器方式对比

对比项 页式虚拟存储器 段式虚拟存储器 段页式虚拟存储器
划分依据 按固定大小分页 按逻辑结构分段 先分段,再分页
地址空间 一维线性地址 二维(段号+段内偏移) 三维(段号+页号+页内偏移)
大小 页面大小固定 段长可变 段长可变,页大小固定
碎片 内部碎片,无外部碎片 外部碎片,无内部碎片 少量内部碎片,无外部碎片
共享与保护 页面级共享,保护粒度粗 段级共享,保护粒度细 段级共享,页级保护
内存分配 简单,按页分配 复杂,需动态分区 较简单,按页分配
地址转换 查页表(1次) 查段表(1次) 查段表+页表(2次)
硬件开销 页表基址寄存器 段表基址寄存器 段表基址寄存器
逻辑性 差,页面无逻辑意义 好,段是逻辑单位 较好,段有逻辑意义
典型应用 早期系统、嵌入式 较少单独使用 现代操作系统(x86、ARM)
⚠️
考点提示
① 页式存储:页面大小固定、内部碎片、地址一维
② 段式存储:段长可变、外部碎片、便于共享保护、地址二维
③ 段页式存储:结合两者优点,现代OS常用,但需两次查表(可用TLB加速)
④ 碎片问题:页式有内部碎片无外部碎片;段式有外部碎片无内部碎片;段页式有少量内部碎片

10. 页面置换算法

当主存空间已满,又需要调入新页面时,需要选择一个页面换出。选择被替换页面的算法称为页面置换算法。

10.1 常用页面置换算法

算法 思想 优点 缺点
FIFO 先进先出,淘汰最早进入的页面 实现简单 可能产生Belady异常
LRU 最近最少使用,淘汰最久未使用的页面 性能好,无Belady异常 实现复杂,需硬件支持
OPT 最佳置换,淘汰未来最久不使用的 理论最优 无法实现,用于评价其他算法
CLOCK 时钟算法,循环检查访问位 近似LRU,实现简单 性能略低于LRU
⚠️
Belady异常 对于FIFO算法,可能出现分给进程的物理页面数增加,缺页次数反而增加的异常现象。栈式算法(如LRU、OPT)不会出现Belady异常。

11. 外部存储器

外部存储器(辅助存储器)用于存放大量数据和程序,CPU不能直接访问,需要通过I/O接口调入主存。主要包括磁盘存储器和固态硬盘(SSD)。

11.1 磁盘存储器

磁盘存储器利用磁记录技术存储数据,容量大、价格低、速度慢,是传统的主要外存设备。

磁盘物理结构

磁盘结构示意图
磁道0
磁道1
磁道2
磁道 (Track)
磁盘上的同心圆轨道,每个盘面有若干磁道,从外向内编号0, 1, 2...
扇区 (Sector)
磁道的分段单位,每个扇区存储固定数据量(通常512B或4KB),是磁盘的最小读写单位
柱面 (Cylinder)
所有盘面上相同编号磁道组成的圆柱面,磁盘地址:柱面号 + 盘面号 + 扇区号
盘面 & 磁头
磁盘有多张盘片,每张盘片有上下两个盘面,每个盘面对应一个磁头
磁盘数据组织:数据按柱面组织,同一柱面的磁道连续存放,减少磁头移动次数。访问时间 = 寻道时间 + 旋转延迟 + 传输时间。

磁盘格式化与分区

🔧 低级格式化(物理格式化)

将空白盘面划分为磁道和扇区
写入扇区标识信息和校验信息
通常在出厂前由厂商完成
标记坏扇区并跳过

📁 高级格式化(逻辑格式化)

在分区上建立文件系统
如FAT32、NTFS、EXT4
写入文件系统管理信息
用户操作层面完成

💡
磁盘分区
将物理磁盘划分为多个逻辑区域,每个分区可独立安装不同的文件系统。
分区表类型:MBR(最多4个主分区)和GPT(支持更多分区,现代标准)。

磁盘读写原理

  • 寻道时间:磁头移动到目标磁道所需时间,约3~15ms,是主要时间开销
  • 旋转延迟:目标扇区旋转到磁头下方所需时间,平均为旋转半圈的时间
  • 传输时间:数据实际传输的时间,取决于转速和数据密度
平均访问时间 T = 平均寻道时间 + 平均旋转延迟 + 传输时间
例:7200RPM磁盘,平均旋转延迟 = 0.5 × (60/7200) = 4.17ms
磁盘参数 常见值 说明
转速 5400/7200/10000/15000 RPM 影响旋转延迟和传输速度
平均寻道时间 3~15ms 机械运动,速度较慢
数据传输率 50~200MB/s 内部传输率(接口速率更高)
扇区大小 512B / 4KB 现代硬盘倾向使用4KB扇区

11.2 固态硬盘 (SSD)

固态硬盘使用Flash存储芯片作为存储介质,无机械部件,速度快、功耗低,但存在擦写次数限制。

Flash存储单元

SSD内部结构与Flash单元
SSD Block/Page 结构:
P0
P1
P2
P3
P4
P5
P6
P7
↑ Block包含多个Page (每Page 4KB~16KB)
页 (Page)
最小读写单位,大小通常4KB~16KB
可写入但写入前必须先擦除
块 (Block)
最小擦除单位,包含64~256页
擦除后所有页可重新写入
Flash类型
SLC(1位) > MLC(2位) > TLC(3位) > QLC(4位)
容量↑ 但寿命↓ 速度↓
Flash写入特性:Page可单独写入,但必须先擦除整个Block。这导致SSD写入性能低于读取性能,且存在写入放大问题。

SSD读写性能特性

📖
读取性能
顺序读取500MB/s+
随机读取
延迟~0.1ms
✏️
写入性能
顺序写入300MB/s+
随机写入较慢
写入放大存在
🔄
擦除限制
SLC~100K次
MLC~10K次
TLC/QLC~1K次

磨损均衡技术

为延长SSD寿命,需要让各Block的擦写次数均匀分布,避免某些Block过早损坏。

磨损均衡示意

Block A (动态磨损均衡) 23%
Block B 25%
Block C 22%
Block D (无磨损均衡) 85%

磨损均衡使各Block擦写次数趋于均匀,延长整体寿命。无均衡时某些Block可能过早损坏。

🔄 动态磨损均衡

在写入新数据时,选择擦写次数较少的Block
需要FTL(Flash转换层)维护Block信息
对频繁写入的数据效果好

📦 静态磨损均衡

将长期不更新的冷数据迁移到高磨损Block
释放低磨损Block用于热数据
需要周期性执行迁移操作

⚠️
写入放大 (Write Amplification)
实际写入量大于逻辑写入量的现象。因Page写入需先擦除Block,且磨损均衡需要数据迁移。
WA因子通常在2~10之间,影响SSD寿命和写入性能。

磁盘 vs SSD 对比

特性 机械磁盘 (HDD) 固态硬盘 (SSD)
存储介质 磁记录技术 Flash存储芯片
随机访问性能 慢(需要寻道+旋转) 快(电子访问)
顺序读写 较稳定 读取快,写入有放大
功耗 较高(机械运动) 较低
寿命 理论上无限 受擦写次数限制
单位容量价格 较高(但持续下降)
适用场景 大容量存储、冷数据 高性能、频繁访问