1.4 CPU阿甘
沿取指、译码、执行、缓存访存、流水线提交追踪指令吞吐,用 CPI、依赖和停顿证据解释 CPU 性能。
学习目标
- 能沿取指、译码、执行、访存和提交追踪指令的阶段状态与结果
- 能用指令数、CPI、周期时间、缓存命中率和流水线停顿解释性能,而不是只看主频
- 能在数据依赖、缓存未命中和分支预测失败场景中定位首个停顿并重放验证
1.4 CPU阿甘
本页依据刘欣《码农翻身》(2018 年第 1 版)及出版社公开书目信息,独立重构 1.4 CPU阿甘。正文、代码、图示、实验和练习都是本课程重新设计的教学材料,不复制原书正文、插图、练习答案或代码。
CPU 的工作不是“主频越高就越快”。一条指令经历取指、译码、执行、可能的访存和提交;流水线让不同指令的阶段重叠,但数据依赖、缓存未命中和分支改变会插入停顿或清空。性能解释必须把指令数、CPI、周期时间和停顿原因放回同一条轨迹。
三个会让 CPU 模型失真的陷阱
五个目录节点到机制证据
1.4 CPU阿甘
↡通过取指、译码、执行、访存和提交阶段推进指令,并用周期、CPI、缓存和停顿证据解释结果的 CPU 执行模型。不是把人物故事换成硬件名词,而是固定一条最小指令序列,说明每个阶段的输入、输出和阻塞条件。
性能合同可写成:
如果结果相同但其中一次访存越过缓存层级、依赖被错误忽略或提交顺序不成立,仍应拒绝该实现。最终时间是结果,阶段轨迹才是解释。
启动
↡根据程序计数器取出下一条指令,并把指令与地址带入流水线的阶段。对应取指的机制证据。记录程序计数器、指令地址、取指缓存结果和下一地址;分支或未命中改变路径时,必须说明预取或等待如何处理。
运行
↡指令在译码、执行、访存和提交阶段推进,阶段之间通过操作数、控制信号和结果传递连接。对应指令执行的阶段证据。记录操作数就绪、功能单元、依赖、访存结果和提交顺序,不能只用最终寄存器值推断中间过程。
新装备:缓存
↡利用局部性把近期或相邻数据放在更快层级,并用命中、未命中和填充事件决定访存等待的层级。对应访存的层级证据。缓存命中缩短常见路径,未命中可能等待更低层或主存;记录地址、层级、替换与填充,才能解释 CPI 变化。
自我提升:流水线
↡让不同指令的取指、译码、执行、访存和提交阶段重叠,并在依赖、分支或资源冲突时插入停顿、转发或清空。对应重叠执行的证据。每一周期都应能回答哪些指令占用哪些阶段、哪个条件阻塞了推进,以及提交是否保持架构顺序。
最小可重放实现
expected = instruction_count * cpi * cycle_time
trace = run_pipeline(fixed_program, cache="baseline")
assert trace.committed_value == reference_value
assert trace.cycles == expected_cycles
assert reset(trace) == run_pipeline(fixed_program, cache="baseline")这段草图只表达阶段轨迹与性能合同,不复制书中叙事或代码。实际复核应保存程序版本、指令数、周期、CPI、程序计数器、阶段占用、缓存事件、停顿原因、提交结果和复位结果。
五步复核一条指令序列
1. 固定程序、指令数与性能基线
冻结指令序列、输入、程序计数器、缓存初始状态和周期时间。先按公式预测周期,再观察第一条指令的取指。
Lab
依赖、缓存与流水线实验
只改变一个依赖或访存条件,观察停顿、阶段恢复和提交证据。
独立指令连续推进,缓存全部命中
I1 IF→ID→EX→MEM hit→WB; I2 overlaps; cycles = reference
判定
通过:阶段重叠,提交顺序与基线一致
当前场景:基线流水线;记录 PC、阶段、操作数、缓存层级、停顿周期、CPI 和提交结果。
正常、边界与故障证据
| 样本 | 只改变的变量 | 预期判定 | 必存证据 |
|---|---|---|---|
| 正常 | 独立指令、缓存命中、分支路径稳定 | 阶段推进,提交结果与基线一致 | 指令数、周期、CPI、阶段轨迹 |
| 边界 | 数据依赖、缓存容量、流水线填充或排空 | 在相应阶段停顿并给出额外周期 | 依赖、层级、停顿周期、路径 |
| 故障 | 一次错误转发、未命中处理或分支清空遗漏 | 首个阶段违约可定位,修复后可重放 | 首差、操作数、缓存事件、提交结果 |
故障诊断:先找第一个多出的周期
- 核对算式输入:确认指令数、CPI、周期时间和测量区间,排除把初始化或排空混入基线。
- 核对阶段依赖:按周期排列取指、译码、执行、访存和提交,找第一个操作数未就绪或资源冲突。
- 核对缓存事件:确认访问地址、命中层级、未命中类型、填充和阻塞范围,区分容量、冲突和冷启动。
- 核对路径与提交:检查分支预测、清空、重新取指和提交顺序;修复后从同一缓存基线重放。
术语表
名词解释
本章出现的专业名词,用大白话再讲一遍。
- 1.4 CPU阿甘
通过阶段推进、缓存层级和停顿证据解释指令执行与 CPU 时间的模型。
- 启动
根据程序计数器取出下一条指令并带入流水线的阶段。
- 运行
指令在译码、执行、访存和提交阶段推进的过程。
- 新装备:缓存
利用局部性把数据放在更快层级,并用命中与未命中决定访存等待的机制。
- 自我提升:流水线
让多条指令的阶段重叠,并在依赖、分支或资源冲突时插入控制动作的机制。
练习
练习
问题 1: 两颗 CPU 主频相同,程序运行时间不同,应该补充哪些证据?
问题 2: 后一条指令依赖前一条结果,为什么流水线仍可能出现停顿?
问题 3: 一次缓存未命中使总周期增加,怎样判断它是否阻塞了整条流水线?
本页小结
1.4 CPU阿甘的关键不是把 CPU 想成更快的跑步者,而是能沿取指、译码、执行、访存、提交追踪阶段,说明缓存和流水线怎样改变等待。完成标准是用指令数、CPI、周期时间和停顿证据解释总周期,在依赖、未命中或分支故障中定位首差,并证明复位后结果和轨迹重新一致。