处理器核设计之执行

执行便是根据指令的具体操作类型发散给具体的运算单元进行执行,常见的运算单元为以下几种

  • 算术逻辑运算单元,主要负责普通逻辑运算,加减法运算和移位运算等基本运算。
  • 整数乘法单元,主要负责有符号或者无符号数整数的乘法运算。
  • 整数除法单元,主要负责有符号数或无符号数整数的除法运算。
  • 浮点运算单元,主要负责浮点指令的运算。

一、指令发射、派遣、执行、写回的顺序

将指令发射给运算单元,由运算单元进行执行,然后写回的彼此相对顺序,也是执行阶段需要解决的重要问题,此处涉及两个概念。

  • 派遣:可以是按顺序派遣,也可以是乱序派遣。
  • 发射:可以是按顺序发射,也可以是乱序发射。

(1)在处理器设计中,派遣和发射是两个时常被混用的定义。在简单的处理器中,二者往往说的同一个概念,都是表示指令进行译码之后,被派发到不同的运算单元执行的过程,因此派遣或者发射一般发生在流水线的执行阶段。

(2)在一些比较高端的超标量处理器核中,流水线级数甚多,派遣和发射便可能有了不同的含义,派遣往往表示指令经过译码之后被派发到不同的运算单元的等待队列中的过程,而发射往往表示指令从运算单元的等待队列中(解决了数据依赖性之后)发射到运算单元开始执行的过程。

处理器中发射,派遣,执行,写回的顺序是处理器微架构设计中非常重要的一环,根据顺序的不同,可以分为很多种流派。简述如下:

(1)顺序发射,顺序执行,顺序写回

  • 这种策略往往出现在最简单的流水线的处理器核中,譬如经典的五级流水线,指令按顺序发射,在运算单元中执行和写回Regfile。
  • 这种策略是性能比较低的做法,硬件实现最简单,面积最小。

(2)顺序发射,乱序执行,顺序写回

  • 由于不同的指令类型往往需要不同的运算单元执行周期,比如除法指令往往需要耗费几十个周期,而最简单的逻辑运算仅需要一个周期,因此如果一味地进行顺序执行,则性能太差
  • 乱序执行便是在指令的执行阶段可以由不同的运算单元同时执行不同的指令,比如在除法器执行除法指令期间,ALU也可以执行其他指令,从而提高性能。
  • 但是最终的写回阶段仍要严格低按顺序写回,因此很多时候运算单元要等待其他的指令先写回而将其运算单元本身的流水线停滞。

(3)顺序发射,乱序执行,乱序写回

  • 在上述乱序执行的基础上,如果能够让运算单元也乱序地写回,则可以进一步提高性能。
  • 运算单元的乱序写回方式门类繁多,可以分为很多种不同的实现。举例如下

重排序缓存(ROB Re-Order Buffer),因此运算单元一旦执行完毕后,结果就将写回ROB,而非直接写回Regfile,最好由ROB按顺序写回Regfile。这是一种典型的乱序写回实现,性能很好,不过这种方案也存在着ROB往往面积过大,数据被腾挪写回两次(先从运算单元到ROB,再从ROB到Regfile)而增大动态功耗的问题。

有的处理器并不使用ROB,而是使用同一的物理寄存器组实现,由一个统一的物理寄存器组动态地管理逻辑寄存器组的映射关系,运算单元一旦执行完毕后,就将结果乱序地写回物理寄存器中。但控制相对复杂。

  • 乱序写回还有其他方法可以做到

(4)顺序派遣,乱序发射,乱序执行,乱序写回

  • 在超标量处理器中,指令经过译码后被顺序低派遣到不同运算单元的等待队列中,在等待队列中可以有多条指令等待,待哪一条指令先解决了数据依赖性后便可被先发射到运算单元中开始执行,因此其发射是乱序的。
  • 高性能处理器往往配备ROB或者统一的物理寄存器组,因此运算单元的乱序执行和乱序写回小菜一碟。

二、分支解析

在取指阶段的分支预测功能,对于带条件分支指令,由于其条件解析需要进行操作数运算(比如大小比较操作),流水线在取指阶段无法得知该指令的条件跳转结果是跳还是不跳,只能进行预测。

因此在执行阶段,通常需要使用ALU对该指令进行条件判断运算(比如大小比较操作)。ALU进行条件判断运算的结果将用于解析该分支指令是否真的需要跳转,并且和之前预测的跳转结果进行比对。如果真实的结果和预测的结果不一致,则意味着之前的预测错误,需要进行流水线冲刷,将预测取指所取的指令都舍弃掉,重新按照真实的跳转方向进行取指。

由于分支预测错误造成的流水线冲刷会造成性能损失。流水线级数越深,流水线冲刷造成的性能损失越大。因此理论上来讲,分支预测如果能够发生在比较靠前端(取指)的流水线位置,则相对而言其带来的流水线冲刷的性能损失会相对小一些;如何在功能正确且时序能够满足的情况下,尽量在比较靠前端的流水线位置进行分支解析,是处理器架构设计经常需要考虑的问题。

三、RISC-V架构对于执行的简化

3.1 规整的指令编码格式

指令集编码非常规整,指令所需的通用寄存器索引(Index)都被放在固定的位置。因此指令译码器可以非常便捷地译码出寄存器的索引,然后从通用寄存器组中读出操作数,同样可以很容易地译码出指令的类型和具体信息。

3.2 优雅的16位指令

RISC-V架构的精妙之处在于每一条16位长的指令都能找到一一对应的原始32位指令。因此译码逻辑可以利用此特点将16位指令展开成为其对应的32位指令,从而使得流水线后续部分看到的都是统一的32位指令,执行阶段无须区分指令是16位还是32位指令。

3.3 精简的指令个数

RISC-V架构的指令集数目非常简洁,基本的RISC-V指令数目仅有40多条,加上其他的模块化扩展指令总共几十条指令。指令数目精简也就意味着只需处理更少的情形,简化执行阶段的硬件设计负担。

3.4 整数指令都是两操作数

RISC-V的整数指令的操作数个数均是规整的1操作数或者2操作数指令,没有3操作数指令,这样可以简化操作数读取和数据相关性检测部分的硬件设计。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值