存储层次结构
复习
- 第二十六章:寄存器速度最快,但数量极少
- 第三十章:存储器容量大,但速度比寄存器慢得多,而且内存断电会丢
TL;DR
- 存储器“快、大、便宜“三者不可兼得
- 于是计算机把它们按“寄存器 → 缓存 → 内存 → 外存“叠成金字塔
- 这个结构能成立,靠的是程序的局部性原理
- 每一层都充当下一层的“缓存“
正文
一个绕不开的矛盾
理想的存储器应该同时满足三点:速度快、容量大、成本低。
但现实很残酷:这三者不可能同时满足。快的存储器造价高,大容量的存储器速度慢。就像你不可能既想要一辆跑车的速度,又想要货车的载重,还只花自行车的钱。
怎么办?计算机科学的万能招数又来了——加一层。既然一种存储器满足不了,那就把好几种叠起来用。
存储层次
把不同速度、不同容量的存储器按“金字塔“叠起来:
| 层次 | 典型速度 | 典型容量 | 说明 |
|---|---|---|---|
| 寄存器 | 最快(<1 个时钟周期) | 几百字节 | CPU 内部直接操作 |
| 高速缓存 Cache | 很快(几到几十周期) | 几十 KB ~ 几十 MB | 分 L1 / L2 / L3 |
| 主存(内存) | 较慢(上百周期) | 几 GB ~ 几百 GB | 存放运行中的程序和数据 |
| 外存(硬盘) | 最慢(可达数百万周期) | TB 级 | 长期保存 |
越往上越快越贵越小,越往下越慢越便宜越大。CPU 优先在最快的层次里找数据,找不到再往下一层找。
注意一个漂亮的规律:每一层,都是它下面那一层的“缓存“。 寄存器缓存着内存里最常用的数据,内存缓存着硬盘里要用的数据,一层套一层。
局部性原理
凭什么这么叠就能又快又大又便宜?靠的是一个统计规律——局部性原理(Locality):
- 时间局部性:刚刚访问过的数据,很可能马上又要用(比如循环里反复读的变量)
- 空间局部性:用到了某个数据,很可能接着用到它旁边的数据(比如遍历数组)
因为程序总是“在附近打转“,我们只要把最近用到的一小块数据搬进快速存储,大部分时候就够用了。
这就是层次结构的灵魂:用一小块快而贵的存储,去“兜住“大部分访问,剩下的少数访问才落到又慢又便宜的大容量存储上。
思考题
请分别举一个“时间局部性“和“空间局部性“特别强的例子。如果一个程序两种局部性都很差,会发生什么?
小结
知识点
- 速度、容量、成本三者的矛盾
- 存储层次:寄存器 / 缓存 / 主存 / 外存
- 每层是下层的缓存
- 局部性原理:时间局部性与空间局部性
参考资料
- Wikipedia(zh):存储器层次结构:存储层次的详细介绍
- 《深入理解计算机系统》第 6 章:存储器层次结构
推荐
思考题答案(仅供参考)
- 时间局部性:循环里多次使用的计数器、累加变量;反复调用的函数代码。
- 空间局部性:按顺序遍历数组、逐行扫描矩阵。
- 如果两种局部性都很差(比如在巨大数组里随机跳跃访问),那么每次访问都可能落到慢速内存,层次结构几乎帮不上忙,程序会明显变慢。这也说明数据的组织方式和访问顺序,会实实在在影响程序快慢。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪