处理器-DRAM 鸿沟
每年约扩大 50%,一次访存空转的时间足够执行上千条指令
CS152 · 第 6 课
从这一课开始,课程进入体系结构的第二大主题——存储系统。核心矛盾很直接:处理器和 DRAM 之间的性能差距每年都在扩大,而缓存正是靠"局部性"这一经验规律来弥合这道鸿沟的。
历史数据:微处理器性能每年增长约 60%,而 DRAM 性能每年只增长约 7%。两者的差距因此以复合方式扩大:
\[ \frac{1.60}{1.07} - 1 \approx 0.495 \]
即差距每年扩大约 49.5%,与幻灯片给出的"每年约 50%"基本吻合。一个具体量化例子:一台 4 发射、3 GHz 的超标量处理器,如果要访问一次 100 ns 延迟的 DRAM,在这段时间里本可以执行多少条指令?
\[ \frac{100\text{ ns}}{1/3\text{ GHz}} = \frac{100}{0.333} \approx 300 \text{ 周期}, \quad 300 \times 4 = 1200 \text{ 条指令} \]
重新验算后与幻灯片给出的"1,200 条指令"完全一致——这就是"存储墙"问题的直观体感:一次内存访问的时间,足够处理器做完上千条指令。
与第 5 课引入的术语一致:延迟(latency)是单次操作从启动到可用结果的时间;带宽(bandwidth)是操作被执行的速率;占用率(occupancy)是某部件因处理一个操作而被阻塞(造成结构冒险)的时间。
DRAM 用单个晶体管+电容(1-T cell)存储一个比特,比 SRAM(类似锁存器的交叉耦合结构)更紧凑但需要周期性刷新。一次 DRAM 访问包含三个阶段:
多个 DRAM 芯片并联组成 DIMM(Dual Inline Memory Module),共享时钟/控制/地址信号,数据引脚协同工作凑出更宽的字(例如 16 颗 4 位芯片拼出 64 位总线)。以 Apple M1 为例:128 位数据总线、单引脚速率 4.2 Gb/s,带宽为:
\[ 128 \times 4.2\text{ Gb/s} = 537.6\text{ Gb/s} \div 8 \approx 67.2\text{ GB/s} \]
与幻灯片给出的"约 68 GB/s"基本一致(小的舍入差异,不构成实质性矛盾)。
存储层级的基本原则:容量 寄存器 << SRAM << DRAM;延迟同样递增;片上带宽远大于片外带宽。存储层级之所以有效,靠的是程序访存模式中普遍存在的两种局部性(Hatfield & Gerald 1971 的真实访存轨迹散点图直观展示了这一点):
缓存持有主存位置的副本:每一行(line/block)包含一个地址标签(tag)和一块数据;命中(hit)指在缓存中找到,直接返回;缺失(miss)指未找到,需要从主存读取整个数据块、等待、返回数据并更新缓存。缓存读取的核心问题是"应该替换哪一行?"(下一课展开)。
三种放置策略(以地址为 32 的第 12 号数据块为例):
| 策略 | 说明 | 12 号块的位置 |
|---|---|---|
| 全相联(Fully Associative) | 可以放在任意一行 | 任意位置 |
| 组相联(Set-Associative) | 只能放进某一组内的任意一行 | 4 组时,12 mod 4 = 0 → 第 0 组 |
| 直接映射(Direct-Mapped) | 只能放进唯一确定的一行 | 8 行时,12 mod 8 = 4 → 第 4 行 |
直接映射缓存把地址拆分成三段:Tag(t 位)| Index(k 位,选出 2^k 行中的一行)| 块内偏移(b 位)。命中判断:用 Index 选出对应行,用比较器核对存储的 Tag 是否与地址的 Tag 一致,并且该行的 Valid 位为真。组相联缓存则是并行运行多组(每组一个 Tag 比较器),命中信号做"或"运算后再用多路选择器选出数据。全相联缓存没有 Index 字段,每一行都并行比较自己的 Tag。
问题 1:一台 4 发射、3 GHz 的超标量处理器,在等待一次 100 ns 的 DRAM 访问期间,理论上最多可以执行多少条指令?
问题 2:在一个 4 组的组相联缓存中,数据块 12 应该被放进第几组?
问题 3:下列哪一项准确描述了"空间局部性"(而非"时间局部性")?
每年约扩大 50%,一次访存空转的时间足够执行上千条指令
行访问 → 列访问 → 预充电
时间局部性(重复访问)、空间局部性(相邻访问)
全相联、组相联(mod N)、直接映射(mod 行数)
sp23/lecture_slides/L06_Memory.pdf(UC Berkeley CS152/CS252A, Spring 2023, Sophia Shao)