存储器系统:主存、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共同完成,对应用程序员透明。
1
CPU → Cache → 主存 → 辅存

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访存过程

  1. CPU将地址送MAR → 地址线 → 主存地址寄存器 → 地址译码。
  2. CPU将读写信号送控制线 → 主存读写控制电路。
  3. 读操作:主存读出数据 → 数据线 → MDR。
  4. 写操作: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的基本工作原理

  • 块长:Cache块(行)与主存块大小相等。

  • **命中率(p)**:
    $$
    p = \frac{\text{命中次数}}{\text{总访问次数}}
    $$

  • 平均访问时间
    $$
    T_a = T_c + (1-p) \times T_m
    $$


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; // 4字节
char b; // 1字节
short c; // 2字节
}; // sizeof(A) = 8

struct B {
char b; // 1字节
int a; // 4字节
short c; // 2字节
}; // sizeof(B) = 12