计算机体系结构核心 20% — 把”为什么慢”算出来
一句话:性能只有一条主公式
时间 = 指令数 × CPI × 时钟周期,存储层次只有三个数字(寄存器 1 周期、L2 约 10 周期、内存约 200 周期)。抓住这两件事,就抓住了体系结构 80% 的实用知识。
🎯 这 20% 能解决哪些问题
| 常见困惑 | 本质 | 本页答案 |
|---|---|---|
| 主频高就一定快吗 | 主频不进入唯一性能公式的分母判断 | 见「一条性能公式」 |
| 循环顺序换一下为什么快 10 倍 | 缓存行与访问局部性 | 见「存储层次」 |
| 多线程加一倍核数没快一倍 | Amdahl 定律 | 见「加速比上限」 |
| 分支预测失败的代价有多大 | 流水线冲刷 | 见「四种冒险」 |
| 数组遍历和链表遍历差在哪 | 预取与局部性 | 见「三条实用准则」 |
一、一条性能公式
[ T = IC \times CPI \times \frac{1}{f} ]
| 符号 | 含义 | 谁能影响它 |
|---|---|---|
| IC(指令数) | 执行了多少条指令 | 编译器、算法、指令集 |
| CPI | 每条指令平均周期数 | 流水线、缓存命中率、分支 |
| f | 时钟频率 | 工艺、功耗预算 |
推论(考试与实际都常考):
- 优化语言层面(如减少指令数)只影响 IC。
- 优化内存访问模式影响 CPI,常比减指令更有效。
- 提高主频受功耗墙限制:功耗 ∝ f × V²,频率涨 20% 可能功耗涨 40%。
二、存储层次:先记住五个数
graph LR R["寄存器<br/>1 周期"] --> L1["L1 缓存<br/>4 周期"] L1 --> L2["L2 缓存<br/>12 周期"] L2 --> L3["L3 缓存<br/>40 周期"] L3 --> M["主存<br/>200 周期"] M --> D["SSD<br/>10 万周期"]
| 层次 | 典型容量 | 命中延迟 | 关键机制 |
|---|---|---|---|
| 寄存器 | 几百字节 | 1 周期 | 编译器分配 |
| L1 | 32–64 KB | 4 周期 | 缓存行 64 B |
| L2 | 512 KB–2 MB | 12 周期 | 组相联 |
| L3 | 8–64 MB | 40 周期 | 多核共享 |
| 主存 | 8–512 GB | 200 周期 | 预取、多通道 |
最有用的一个数字:缓存行 64 字节。一次访存会把相邻 64 B 一起搬进缓存——这解释顺序访问为什么快、
struct字段顺序为什么有讲究。
三、四种流水线冒险
| 冒险 | 原因 | 典型解决办法 |
|---|---|---|
| 结构冒险 | 硬件资源冲突 | 分开指令/数据缓存 |
| 数据冒险 | 后一条依赖前一条结果 | 转发(forwarding)、插入气泡 |
| 控制冒险 | 分支结果未知 | 分支预测、延迟槽 |
| 内存冒险 | 访存顺序 | 内存屏障、一致性协议 |
两个实用结论:
- 分支可预测时代价接近 0;预测失败约损失 15–20 个周期。
- 数据依赖链长(如累加求和)会限制指令级并行;拆成多个累加器即可提速。
四、加速比上限:Amdahl 定律
[ S = \frac{1}{(1-p) + p/s} ]
| 并行比例 p | 无限并行加速比上限 |
|---|---|
| 50% | 2× |
| 80% | 5× |
| 90% | 10× |
| 95% | 20× |
| 99% | 100× |
实践含义:想把程序提速 10 倍,先找那 5% 无法并行的部分。优化串行部分比加核更划算。
五、缓存友好的三条准则
| 准则 | 具体做法 | 收益来源 |
|---|---|---|
| 顺序访问 | 按行遍历二维数组(行主序语言) | 命中整条缓存行 |
| 数据紧凑 | 热字段放一起、避免指针追逐 | 减少缓存行浪费 |
| 分块 | 矩阵乘按 32×32 分块 | 提高 L1/L2 复用 |
反例:链表遍历每次跳指针 → 几乎每次都是缓存未命中,比数组慢 5–20 倍。
六、多核与内存一致性
| 概念 | 一句话 |
|---|---|
| 缓存一致性 | 多核各自缓存同一地址时,需协议(MESI)保证看到同一值 |
| 伪共享 | 两个核改同一缓存行的不同变量,互相失效拖慢 |
| 内存序 | 编译器与 CPU 都可能重排,跨线程共享需屏障 |
伪共享是新手最常踩的坑:多线程计数器数组放在连续内存,性能反而不如单线程。解决:按缓存行对齐填充。
📋 一页速查
| 问题 | 答案 |
|---|---|
| 唯一性能公式 | T = IC × CPI × 1/f |
| 缓存行多大 | 64 字节 |
| 内存延迟 | 约 200 周期 |
| 分支预测失败代价 | 约 15–20 周期 |
| 加速比上限 | 由串行比例决定(Amdahl) |
| 最便宜的提速手段 | 改善访问局部性 |
🔗 相关链接
| 主题 | 链接 |
|---|---|
| 硬件基础概览 | 硬件基础 |
| GPU 并行计算 | GPU 并行计算核心 20% |
| 芯片设计 | 芯片设计核心 20% |
| 量子计算 | 量子计算核心 20% |
| 算法与数据结构 | 算法与数据结构 |