Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

指令流水线技术

本章为进阶内容,零基础读者可以跳过,不影响后续阅读。

复习

  1. 第三十八章:了解了 CPU 按“取指 → 译码 → 执行 → 写回“的循环工作

TL;DR

  • 流水线让多条指令的不同阶段重叠执行,从而成倍提高吞吐率
  • 流水线会遇到数据冒险、控制冒险、结构冒险,需要转发、停顿、预测等手段处理
  • 超标量、乱序执行等是流水线的进一步发展

正文

从洗衣房说起

  假设洗一桶衣服要经过“洗 → 烘 → 叠“三步。如果一个人从头做到尾,一桶接一桶地干,那他大部分时间都在等机器,很浪费。

  但如果有三个人流水作业:一个负责洗,一个负责烘,一个负责叠,那么第一桶在烘的时候,第二桶已经在洗了。虽然单桶的总时间没变,但每小时完成的桶数(吞吐率)大大提高了。

  流水线(Pipeline)就是这个思路用到 CPU 上。

五级流水线

  把指令执行拆成五个阶段:

  • F(Fetch):取指令
  • D(Decode):译码
  • E(Execute):执行
  • M(Memory):访存
  • W(Write-back):写回

  不流水时,一条指令占满五个阶段,下一条只能干等。流水之后,每一拍都有五条指令分别处于五个阶段:

指令1: F  D  E  M  W
指令2:    F  D  E  M  W
指令3:       F  D  E  M  W
指令4:          F  D  E  M  W

  流水线填满后,每个时钟周期就能完成一条指令。前面思考题里那个“1000 条指令只要约 1003 个周期“的答案,就是这么来的。

流水线的冒险

  现实中没这么理想,会出现冒险(Hazard),也就是让流水线卡壳的冲突。主要有三类:

  1. 数据冒险:后一条指令要用前一条还没算出来的结果。
    • 例:ADD R1,R2,R3 后面紧跟 SUB R4,R1,R5,R1 还没写好就要用
    • 解决:转发(把还没写回的结果直接送过去)、必要时停顿(插几个空拍)
  2. 控制冒险:遇到分支跳转,不知道下一条该取哪里。
    • 解决:分支预测(猜一把,猜错再倒回来)、延迟槽等
  3. 结构冒险:多条指令抢同一个硬件资源(比如同时要访问存储器)。
    • 解决:把指令缓存和数据缓存分开、增加功能部件

更进一步

  在流水线的基础上,工程师们还发明了:

  • 超标量:一条流水线不够,就并排开好几条,一拍发射多条指令
  • 乱序执行:谁的数据先准备好谁先算,不必死守程序顺序,最后再按顺序提交结果
  • 寄存器重命名:消除指令间不必要的数据依赖,让并行更充分

  这些技术让现代 CPU 能用几百甚至上千条“在途指令“来填满流水线。它们已经属于计算机体系结构的高阶内容,这里点到为止,知道有这么回事即可。

思考题

  流水线把速度提高了,代价是什么?为什么流水线级数不是越多越好?

小结

知识点

  • 流水线的基本思想与五级流水线
  • 数据冒险、控制冒险、结构冒险
  • 转发、停顿、分支预测
  • 超标量与乱序执行

参考资料

  1. Wikipedia(zh):指令流水线:流水线的基本概念
  2. Wikipedia(zh):超标量处理器:超标量技术
  3. Wikipedia(zh):乱序执行:乱序执行原理

思考题答案(仅供参考)

  代价是复杂度:流水线级数越多,每一级能分到的活儿就越少,而“填满“和“排空“流水线的固定开销、冒险带来的停顿、时钟同步的代价都会上升。而且级数越多,一旦遇到分支预测失败,需要倒回去的指令也越多。所以级数要取一个平衡点,不是越多越快。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪