指令流水线与超标量处理器

RISC和CISC

现代的通用处理器从指令集方面可分为精简指令集RISC和复杂指令集CISC。最初的处理器都是使用CISC指令集,力求在一条指令内完成很多事情,并用很多指令覆盖到各种各样的操作。而后基于这样一个观察结果:“80%的CISC指令只在20%的时间被使用”,RISC就诞生了,其思想是让那经常使用的20%的指令使用硬件来实现,而对于剩下的80%的指令使用软件来模拟,由此来简化硬件的设计。同时,不像CISC指令长度可以变化,将RISC指令采用等长的方法,更便于使用流水线。每条RISC指令的长度都是32位,降低了解码的难度,易于流水线设计,使得RISC指令集的处理器有更高频率。

一、流水线的多发技术

  1. 超标量技术(又称动态多发技术):
    • 每个时钟周期内可并发多条独立指令
    • 要配置多个功能部件
    • 不能调整指令的执行顺序
    • 通过编译优化技术,把可并行执行的指令搭配起来
      请添加图片描述
  2. 超流水技术
    • 在一个时钟周期内再分段
    • 一个时钟周期内一个功能部件使用多次
    • 不能调整指令的执行顺序
    • 靠编译程序解决优化问题
      请添加图片描述
  3. 超长指令字
    • 由编译器挖掘出指令间潜在的并行性
    • 将多条能并行操作的指令组合成一条
    • 具有多个操作码字段的超长指令字(可达几百位)
    • 采用多个处理部件
      请添加图片描述

二、超标量流水器

1. 标量和超标量处理器

现代的通用处理器从实现方式可分为标量和超标量两种。标量处理器每周期最多执行一条指令,一般按照程序中指定的顺序来执行(顺序执行),这种方式制约了处理器性能的提高,于是就有了超标量处理器。

超标量处理器能够在一个周期内执行多条指令,这样可以缩短一个程序的执行时间,指令在处理器中可以按照程序中指定的顺序执行,也可以不遵循这个顺序,只要指令的源操作数准备好了,它就可以执行,这种方式称为乱序执行。

当然乱序执行也不能改变程序本来的功能。在超标量处理器中,还需要一些方法来使这些乱序执行的指令看起来仍然按照程序中指定的顺序更改处理器的状态,在超标量处理器中的这些功能就注定了它的复杂性。相比于标量处理器,它需要更多的硬件资源和更高的功耗。

2. 为什么需要超标量

  1. 影响程序执行时间的因素:
    一个程序执行的时间 = T o t a l I n s t r u c t i o n s × C y c l e s I n s t r u c t i o n s × S e c o n d s C y c l e 一个程序执行的时间=Total Instructions \times \frac{Cycles}{Instructions} \times \frac{Seconds}{Cycle} 一个程序执行的时间=TotalInstructions×InstructionsCycles×CycleSeconds
    • Total Instructions对应程序总共需要执行的指令个数,影响因素有算法、编译器、ISA
    • C y c l e s I n s t r u c t i o n s \frac{Cycles}{Instructions} InstructionsCycles对应CPI,影响因素有Microarchitecture(微架构)
    • S e c o n d s C y c l e \frac{Seconds}{Cycle} CycleSeconds对应时钟频率,影响因素有工艺、Microarchitecture(微架构)
  2. 由上可知,加快处理器执行程序的速度有以下三种策略
    • 减少程序中指令的数量:
      • 取决于程序本身要完成的工作量、实现某个功能所选择的算法、编译器强大与否、指令集是否会对某些特殊的功能有扩展(如使用扩展的特殊指令集可以大大减少指令的数量)
    • 减少每条指令在处理器中执行所需要的周期数:
      • 对于非流水线的处理器,需要多个周期才能执行一条指令;对于普通的流水线处理器,每周期最多执行一条指令;对于超标量处理器,可以每周期执行多于一条的指令;再比如对于VLIW(超长指令字)结构的处理器中每周期也可执行多于一条的指令。处理器采用何种架构实现称为微架构
    • 减少处理器的时钟周期(即增大CPU的时钟频率)
      • 在进行处理器的微架构设计时,可以通过精巧的电路设计、更深的流水线来减少处理器的时钟周期,现代处理器的设计中,优秀的EDA工具也可帮助减少处理器的时钟周期。此外还有一个更关键的因素,即硅工艺。硅工艺的进步能够制造出更快更省电的处理器
    • 上述三种策略是彼此制约的
      • 更小的CPI要求每周期执行更多条指令,这样会导致处理器的时钟周期很难降下来;而很小的时钟周期又很难容下复杂的逻辑设计,虽然可以通过更深的流水线来获得小的时钟周期,但却导致处理器在各种预测失败时有更大的惩罚,严重增大了处理器CPI,并增大了功耗,造成“高频低能”的后果
  3. 超标量处理器–为降低CPI而诞生
    在超标量处理器中,每周期可从I-Cache中取出n条指令送到处理器的流水线中,处理器在每周期内也最少可以同时执行n条指令。
  4. 超标量处理器与超长指令字VLIW的区别:
    超标量处理器是靠硬件自身来决定哪些指令可以并行执行;而VLIW处理器则是依靠编译器和程序猿自身来决定哪些指令可以并行执行。
    对于通用处理器来说,还是超标量结构更为适合。程序猿可以抛开底层硬件的实现细节,专注于软件本身的功能,且这个程序可以运行在任何支持该指令集的处理器上,这是通用处理器所必须具有的特性,VLIW处理器则无法实现这个功能。但VLIW在功能专一的专用处理器领域可有一番大作为
  5. 超标量处理器设计的难点举例
    • 分支预测:实现精确的分支预测算法需要复杂的硬件资源,会导致其无法在一个周期内完成。而分支预测若不能在一个周期给出预测结果,那么处理器就无法利用预测信息进行连续的取指令,这样处理器性能就会下降
    • load/store:若load/store指令按照完全乱序的方式执行,虽然会获得最大的IPC,却会导致load/store指令之间的相关性检查变得非常复杂。且一旦发现相关性违例,还需要复杂的恢复机制,这样增加了硬件复杂度和功耗
    • Checkpoint的个数和硬件的面积之间的矛盾
    • 发射队列个数和仲裁电路复杂度的矛盾
    • 每周期可同时执行的指令个数与寄存器堆端口个数的矛盾
    • 等等

3. 指令流水线过程涉及到的一些知识

  1. 虚拟存储器:
    处理器在取指令的时候,若送出的是虚拟地址,那么首先需要被转化为物理地址,然后才能取指令
  2. Cache:
    一般的指令都是从I-Cache中取出来并送到流水线中的,因此流水线始于I-Cache
  3. 分支预测:
    也是取指令阶段发生的事情。因为超标量处理器的流水线比较深,导致分支指令的结果在很晚的时候才能得到,一旦发现这个结果和预想的不一样,那么流水线中的很多指令都是没有用的,需要抹掉并从正确的地址取指令,这样就降低了处理器的执行效率。因此要对分支指令使用比较准确的预测算法,从而在取指令阶段就可以提前知道分支指令的结果
  4. 指令解码:
    一旦指令从存储器中取出来后,就需要进行解码(涉及到指令集体系ISA的相关知识)。在超标量处理器中,由于每周期需要对多条指令进行解码,会引入一些新的问题,比如指令之间存在的相关性,以及一些复杂指令的处理等
  5. 硬件的寄存器重命名:
    指令经过解码后,就可以得到它的源寄存器和目的寄存器了。但为了尽量并行执行指令,需要消除指令之间存在的假的相关性,这些相关性都是和寄存器的名字相关的。通过使用不同的寄存器名字,可以消除这些相关性。于是在处理器内部使用了数量多于指令集中定义的寄存器,称为物理寄存器,而指令集中定义的寄存器称为逻辑寄存器。寄存器重命名的过程就是将逻辑寄存器动态地映射到不同的物理寄存器,以消除指令之间存在的假的相关性,从而使这些指令可以并行执行
  6. 指令的发射:
    当指令经过寄存器重命名后,就可以在处理器内部的功能单元FU中执行了。但为了获得最高的性能,超标量处理器多采用乱序执行的方式,只要一条指令的操作数准备好了,即使它之前的指令还没准备好,它也可以送到FU中执行。这种方式可以最大限度地利用处理器内部的硬件资源,从而提高处理器的执行效率。发射阶段正是用来实现这个功能的,所有经过寄存器重命名的指令都会放到一个缓存(发射队列)中,在其中监测每条指令是否已经准备好了,并按照一定算法,从那些已经准备好的指令中选择合适的指令送到FU中执行,这个过程称为发射。指令到了这个阶段,就变为乱序执行了,而在这个阶段之前,都遵循着程序中指定的顺序
  7. 指令在FU中的执行:
    指令被发射之后,就会到对应的FU中开始执行。不同种类的指令需要不同的FU,在超标量处理器中,都会使用多个FU,它们可以并行执行不同指令。旁路网络可以缩短相关指令之间执行的时间,但会使处理器内部的布线资源变得更复杂,现代一些处理器采用了Cluster结构来缓解这种矛盾。同时,访问存储器的load/store指令也需要一些特殊的方法来加速它们的执行速度
  8. 流水线的最后一个阶段:提交
    指令经过FU的执行而得到结果后,并不会马上使用这个结果对处理器的状态进行更新,这是由于指令的执行是按照乱序来执行的,由于分支预测失败和异常等原因,一条指令的结果未必是正确的。而且为了使程序在处理器内部的执行看起来和程序中指定的顺序是一样的(这是串行程序必须的),也需要这些乱序执行的指令按照程序中指定的顺序对处理器的状态进行更新。为了实现这个功能,一条指令在FU中执行完毕后,先将它的结果写到一个缓存(重排序缓存ROB)中,(在流水线的寄存器重命名阶段,每条指令都已经按照程序中指定的顺序写到了ROB中,执行完毕后只需将结果写入ROB对应的地方即可)。当ROB中最旧的那几条指令已经得到结果,且不存在分支预测失败或异常等特殊情况的话,就可以离开ROB,使用它的结果对处理器的状态进行更新,这个过程称为指令的退休。一旦指令经过了这个状态,就再也不能被撤销了。

4. 普通处理器的流水线

  1. 流水线的划分需满足:
    • 每个阶段所需要的时间都是近似相等的,最长的流水段所需的时间决定了整个处理器的周期时间
    • 流水线中每个阶段的操作都会被重复执行。虽然不同指令所需要的操作不同,但并不影响流水线的执行,如算术运算类型的指令不需要访问存储器,则它只需要在流水线的访问存储器阶段什么都不做即可
    • 流水线中每个阶段的操作都和其他流水段相互独立互不相干。这一条最难满足,因为现实中指令之间存在各种相关性,如先读后写(RAW)相关性,会导致流水线的各个阶段之间存在复杂的关系。
  2. RISC指令集天生是为流水线而存在的
    对于复杂的CISC指令集,指令长度不等,执行时间不等,所以直接实现流水线比较复杂;而对于一般的精简指令集RISC来说,指令的长度相等,每条指令所完成的任务比较规整,因此非常容易使用流水线来实现
  3. 一个经典的RISC处理器流水线–五级流水线:
    • Fetch:取指令,使用PC寄存器的值作为地址,从I-Cache中取出指令,并将指令存储在指令寄存器中
    • Decode & Regfile read:将指令进行解码,并根据解码出的值来读取寄存器堆,得到指令的源操作数
    • Execute:根据指令的类型完成计算任务,如对算术类型的指令完成算术运算,对访问存储器类型的指令完成地址的计算等
    • Memory:访问D-Cache,只对访问存储器类型的指令(如load/store)起作用,其他类型的指令在这个流水段不会做任何事情
    • Write back:若指令存在目的寄存器,则将指令的最终结果写到目的寄存器中
  4. 指令流水线的难题:结构冲突、控制冲突、数据冲突

5. 超标量处理器的流水线

  1. 不同阶段的顺序和乱序
    对于【取指令】和【解码】阶段,很难也没有意义实现乱序执行;【将指令送到对应的功能单元中执行】这个阶段可以实现乱序执行,因为只要指令的源操作数准备好了就可以先于其他指令执行;【写回】阶段可以实现乱序执行;【提交】阶段(表示一条指令被允许更改处理器的状态)只能顺序执行

未完待续…

6. 超标量流水线有三种执行模式:按序发射、按序完成;按序发射、无序完成;无序发射、无序完成

假定一个2-发射超标量处理器的指令执行过程分为取指(IF)、译码(ID)、执行(Ex)、写回(WB)四个阶段,其中IF、ID、WB在一个时钟周期内完成,这三个阶段可同时有两条指令执行。
Ex阶段有三个执行部件:1)访存部件:用于完成数据Cache访问,需要1个时钟周期;2)整数ALU:用来完成ALU操作,需要两个时钟周期;3)整数乘法器:用来完成乘法运算,需要三个时钟周期。整数ALU和乘法器均采用流水化方式执行
假定一个如下图所示的指令序列在该处理器上执行,则三种模式执行指令的过程具体细节是什么?
请添加图片描述

解:
由题意可知,某个时钟周期内,处理器中最多有两条指令在取指、两条在译码、两条在写回,一条在访存、两条在进行ALU操作(因为说ALU采用流水化方式执行)、三条在乘法运算,即最多有12条指令正在被处理。(理想情况,实际上指令不一定正好和功能部件一一对应,且指令之间还存在相互关联,因此很多情况下并不是每个功能部件的每个流水段都能被充满。

接下来分析指令,如图可知,指令i1和i2($2+$1->$2)、i3和i4、i5和i6之间具有数据相关性。i1和i2是写后读,i3和i4是读后写,i5和i6是写后读+写后写。因此,必须保证:i1和i2、i5和i6不能同时发射,并要按序完成;i3和i4要保证i3在读$4之前,i4不能写$4

下图分别给出了“按序发射、按序完成”、“按序发射、无序完成”、“无序发射、无序完成”三种指令模式下指令序列的执行过程

  1. 按序发射、按序完成
    请添加图片描述
  2. 按序发射、无序完成
    请添加图片描述
  3. 无序发射、无序完成
    请添加图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值