流水线设计

来源:互联网 发布:2016中美贸易逆差数据 编辑:程序博客网 时间:2024/04/28 06:36

流水线设计就是将组合逻辑系统地分割,并在各个部分(分级)之间插入寄存器,并暂存中间数据的方法。目的是提高数据吞吐率(提高处理速度)。

       流水线缩短了在一个时钟周期内给的那个信号必须通过的通路长度,从而可以提高时钟频率。例如:一个2级组合逻辑,假定每级延迟相同为Tpd,无流水线的总延迟就是2Tpd,可以在一个时钟周期完成,但是时钟周期受限制在2Tpd;如果使用流水线,每一级加入寄存器(延迟为Tco)后,单级的延迟为Tpd+ Tco,每级消耗一个时钟周期,流水线需要2个时钟周期来获得第一个计算结果,称为首次延迟,它要2*(Tpd+Tco),但是执行重复操作时,只要一个时钟周期来获得最后的计算结果,称为吞吐延迟(Tpd+Tco);可见只要Tco小于Tpd,流水线可以提高速度。

       实现流水线的代价:

1.消耗寄存器-就是消耗硅片面积(想想20级流水线的某著名CPU吧)
2.流水线长则消耗更多时钟周期。(如果流水线反复启动,则会损失速度,想想某CPU著名的高频率低效能吧)


    下面附上一段流水线在CPU设计中的应用和问题进行简要介绍

  对于一条具体的指令执行过程,通常可以分为五个部分:取指令,指令译码,取操作数,运算(ALU),写结果。其中前三步一般由指令控制器完成,后两步则由运算器完成。按照传统的方式,所有指令顺序执行,那么先是指令控制器工作,完成第一条指令的前三步,然后运算器工作,完成后两步,在指令控制器工作,完成第二条指令的前三步,在是运算器,完成第二条指令的后两部……很明显,当指令控制器工作是运算器基本上在休息,而当运算器在工作时指令控制器却在休息,造成了相当大的资源浪费。解决方法很容易想到,当指令控制器完成了第一条指令的前三步后,直接开始第二条指令的操作,运算单元也是。这样就形成了流水线系统,这是一条2级流水线。
  如果是一个超标量系统,假设有三个指令控制单元和两个运算单元,那么就可以在完成了第一条指令的取址工作后直接开始第二条指令的取址,这时第一条指令在进行译码,然后第三条指令取址,第二条指令译码,第一条指令取操作数……这样就是一个5级流水线。很显然,5 级流水线的平均理论速度是不用流水线的4倍。
  流水线系统最大限度地利用了CPU资源,使每个部件在每个时钟周期都工作,大大提高了效率。但是,流水线有两个非常大的问题:相关和转移。
  在一个流水线系统中,如果第二条指令需要用到第一条指令的结果,这种情况叫做相关。以上面哪个5级流水线为例,当第二条指令需要取操作数时,第一条指令的运算还没有完成,如果这时第二条指令就去取操作数,就会得到错误的结果。所以,这时整条流水线不得不停顿下来,等待第一条指令的完成。这是很讨厌的问题,特别是对于比较长的流水线,比如20级,这种停顿通常要损失十几个时钟周期。目前解决这个问题的方法是乱序执行。乱序执行的原理是在两条相关指令中插入不相关的指令,使整条流水线顺畅。比如上面的例子中,开始执行第一条指令后直接开始执行第三条指令(假设第三条指令不相关),然后才开始执行第二条指令,这样当第二条指令需要取操作数时第一条指令刚好完成,而且第三条指令也快要完成了,整条流水线不会停顿。当然,流水线的阻塞现象还是不能完全避免的,尤其是当相关指令非常多的时候。
  另一个大问题是条件转移。在上面的例子中,如果第一条指令是一个条件转移指令,那么系统就会不清楚下面应该执行那一条指令?这时就必须等第一条指令的判断结果出来才能执行第二条指令。条件转移所造成的流水线停顿甚至比相关还要严重的多。所以,现在采用分支预测技术来处理转移问题。虽然我们的程序中充满着分支,而且哪一条分支都是有可能的,但大多数情况下总是选择某一分支。比如一个循环的末尾是一个分支,除了最后一次我们需要跳出循环外,其他的时候我们总是选择继续循环这条分支。根据这些原理,分支预测技术可以在没有得到结果之前预测下一条指令是什么,并执行它。现在的分支预测技术能够达到90%以上的正确率,但是,一旦预测错误,CPU仍然不得不清理整条流水线并回到分支点。这将损失大量的时钟周期。所以,进一步提高分支预测的准确率也是正在研究的一个课题。
  越是长的流水线,相关和转移两大问题也越严重,所以,流水线并不是越长越好,超标量也不是越多越好,找到一个速度与效率的平衡点才是最重要的。