指令流水线技术
复习
- 指令周期:CPU 执行一条指令要经过取指、译码、执行和写回
- 数据通路:不同阶段会使用不同部件
- 中央处理器:极简 CPU 已经能正确运行程序
本章讨论如何把机器做快。跳过它,不影响后面连接外部设备。
TL;DR
- 流水线让多条指令同时处于不同阶段
- 它提高单位时间完成的指令数,却不会缩短单条指令的全部路程
- 依赖与跳转会让流水线等待或清空
正文
洗一件衣服要洗、烘、叠三步。若第一件全部完成才开始第二件,洗衣机烘干时,负责洗的设备就在闲着。
CPU 也一样。一条指令执行时,取指部件、译码部件和 ALU 不会始终同时忙。于是可以让下一条指令提前进入空下来的阶段:
指令 1:取指 译码 执行 写回
指令 2: 取指 译码 执行 写回
指令 3: 取指 译码 执行 写回
流水线装满后,理想情况下每一拍都能完成一条指令。单条指令仍要走完所有阶段,变快的是整批指令的吞吐量。
性能用什么衡量
衡量一台机器快不快,不能只看某一个数字,而要看它们怎样相乘:
程序执行时间 = 指令数 × 平均每条指令的周期数(CPI) × 时钟周期
想让时间更短,就有三条路:减少要执行的指令数、降低每条指令平均花几拍(CPI)、或者让时钟走得更快(提高主频)。这三条,分别对应算法与编译器、CPU 结构、以及硬件工艺。“更快”从来不是单一因素,而是这几项共同作用的结果。
后一条等着前一条
若指令 2 立刻要用指令 1 尚未写回的结果,它就不能放心执行。这叫数据冒险。CPU 可以把刚算出的结果直接转给下一阶段,也可以停一拍等待。
若遇到跳转,取指部件还不知道下一条该从哪里取,这叫控制冒险。CPU 可以先猜一条路;猜错后,把错误取进来的指令清掉,回到正确地址。
这就是流水线的主意:让本来闲着的部件同时工作。 代价是安排并行比排队更复杂。
至此,CPU 内部已经完成。接下来把视线移到盒子外面:CPU、存储器和外设之间,不能每两块都单独拉满一套线。
思考题 1
一条指令分为 4 个阶段。理想流水下,执行 100 条指令大约需要多少拍?为什么不是 25 拍?
思考题 2
流水线能提高吞吐量,却几乎不缩短单条指令走完全程的时间。这两件事为什么不是一回事?
小结
知识点
- 流水线让不同指令的不同阶段重叠
- 流水线提高吞吐量
- 数据依赖和跳转会造成冒险
参考资料
- Wikipedia(zh):指令管线:把指令拆分重叠执行的流水线技术
- Wikipedia(zh):分支预测:缓解控制冒险的常见手段
思考题答案(仅供参考)
思考题 1
大约需要 4 + 99 = 103 拍:第一条走完 4 个阶段,此后理想情况下每拍再完成一条。不是 25 拍,因为每个阶段每拍通常只能接纳一条指令,不能在一拍里完成 4 条完整指令。
思考题 2
吞吐量说的是单位时间完成的指令数,流水线让多个阶段并行,确实把它提上去了;而单条指令仍要依次经过取指、译码、执行、写回,路程并没有缩短,所以延迟基本不变。如果流水线出现等待或清空,单条指令甚至可能比不流水更慢。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪