前置知识: 计算机基础

存储系统

00:00
9 min Advanced 2026/6/14

存储系统深度:Cache优化、虚拟存储、TLB、内存管理与存储一致性

1. 存储层次原理

1.1 局部性原理

时间局部性:最近访问的数据很可能在不久后再次被访问。

空间局部性:最近访问数据附近的数据很可能即将被访问。

局部性是存储层次有效性的理论基础。

1.2 存储层次设计目标

其中 为第 层的命中率, 为第 层的访问时间。

2. Cache 优化技术

2.1 降低缺失率

更大块大小:利用空间局部性,但块过大会增加缺失代价。

更大 Cache 容量:直接降低缺失率,但增加命中时间和功耗。

更高相联度:降低冲突缺失,但增加命中时间。

相联度强制缺失容量缺失冲突缺失命中时间
直接映射不变不变最多最短
2路组相联不变不变较少略长
4路组相联不变不变很少较长
全相联不变不变最长

3C 模型

2.2 降低缺失代价

多级 Cache

关键字优先(Critical Word First):缺失时优先加载所需字,其余部分后台加载。

读缺失优先于写:写缓冲可能导致读缺失读到过时数据。

2.3 降低命中时间

小而简单的 Cache:L1 Cache 保持小容量、低相联度。

流水线化 Cache 访问:将 Cache 访问拆分为多个流水线级。

路预测:预测可能命中的路,只访问该路。

2.4 Cache 替换策略

LRU(最近最少使用):替换最久未访问的行。

  • 2路:1 bit 计数器
  • 4路:需要更复杂的计数器
  • 相联度高时开销大

伪 LRU(PLRU):近似 LRU,用树形结构记录访问信息。

随机替换:简单,在某些情况下性能接近 LRU。

2.5 Cache 预取

硬件预取

  • 顺序预取:检测到顺序访问模式时预取下一行
  • 跨步预取:检测固定跨步访问模式

软件预取

// 使用预取指令
__builtin_prefetch(addr, rw, locality);

预取有效性条件:

3. 虚拟存储

3.1 虚拟地址与物理地址

虚拟地址空间由 CPU 生成,物理地址空间对应实际内存:

32 位系统:虚拟地址空间 4GB 64 位系统:虚拟地址空间 (实际实现)

3.2 页式存储

页表映射

页表项(PTE)结构

┌──────┬──────┬──────┬──────┬──────┬──────┐
│ 有效位│ 读写位│ 用户位│ 脏位  │ 访问位│ 物理页号│
└──────┴──────┴──────┴──────┴──────┴──────┘

3.3 多级页表

32 位地址,4KB 页,4B PTE:

  • 单级页表: 项 × 4B = 4MB(每个进程)
  • 二级页表:仅映射已使用的虚拟地址范围

64 位系统通常使用四级页表:

虚拟地址:[PGD索引 | PUD索引 | PMD索引 | PTE索引 | 偏移]

Linux 的四级页表:PGD → PUD → PMD → PTE → 物理页

3.4 反置页表

按物理页号索引而非虚拟页号:

优势:页表大小与物理内存成正比,与虚拟地址空间无关。

4. TLB

4.1 TLB 原理

TLB(Translation Lookaside Buffer)是页表的高速缓存:

虚拟地址 → TLB 查找 → 命中 → 物理地址
                  → 缺失 → 页表查找 → 填充 TLB → 物理地址

4.2 TLB 结构

典型 TLB 参数:

参数典型值
TLB 项数64~512
相联度全相联或高相联
页大小4KB~2MB
命中率>99%
命中时间1 周期
缺失代价20~100 周期

4.3 TLB 与 Cache 的交互

物理索引物理标记(PIPT)

  • Cache 使用物理地址索引和标记
  • TLB 必须先完成翻译
  • 命中时间较长

虚拟索引物理标记(VIPT)

  • Cache 索引使用虚拟地址低位(与物理地址相同)
  • Cache 标记使用物理地址
  • TLB 翻译和 Cache 索引可并行

4.4 超大页(Huge Pages)

标准 4KB 页导致 TLB 覆盖范围有限:

64 项 × 4KB = 256KB,远不够大工作集。

解决方案:使用 2MB 或 1GB 大页。

Linux 透明大页(THP)自动将连续的 4KB 页合并为 2MB 大页。

5. 内存管理

5.1 页面置换算法

最优置换(OPT):置换未来最久不被访问的页,理论最优但不可实现。

FIFO:置换最早进入内存的页,简单但性能差,存在 Belady 异常。

LRU:置换最近最久未访问的页,性能好但实现开销大。

Clock 算法:LRU 的近似实现,使用访问位和循环指针。

改进型 Clock 算法:同时考虑访问位和脏位:

优先级访问位脏位说明
100最佳替换目标
201未访问但已修改
310已访问未修改
411最差替换目标

5.2 工作集模型

进程的工作集 是在时刻 之前的 个时间单位内被访问的页面集合。

抖动(Thrashing):当分配进程物理页数小于工作大小时,频繁发生页面置换。

5.3 页面分配策略

  • 全局置换:所有进程共享物理,可从其他进程夺取页面
  • 局部置换:每个进程固定数量的物理

6. 存储一致性

6.1 Cache 一致性问题

系统中,每个心有自己的私有 Cache,同一内存可能在不同 Cache 中有不同副本

6.2 监听协议(Snooping)

MSI 协议

状态说明
M(Modified)仅本 Cache 有最新数据,与内存不一致
S(Shared)个 Cache 可能有相同数据,与内存一致
I(Invalid)无效

MESI 协议(Intel 使用):

状态说明
M(Modified)已修改,独占
E(Exclusive)未修改,独占
S(Shared)共享
I(Invalid)无效

E 状态优化:当只有一个 Cache 拥有该且未修改时,无需总线广播即可写入。

MOESI 协议(AMD 使用):增加 O(Owner)状态允许共享脏

6.3 目录协议(Directory)

适用于大规模系统,用目录记录每个缓存行的共享信息:

其中 处理数量

目录协议的扩展

  • 映射目录: 空间/
  • 有限目录 空间/
  • 链式目录动态分配空间

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式