3.9 指令传送和预测的先进技术

发布时间 2023-12-10 12:21:11作者: 杨小靖

3.9 指令传送和预测的先进技术

高性能流水线,特别是多发射流水线中仅能够预测分支还不够,需要传送高带宽的指令流(多发射的取值周期变多,预测要等到译码阶段才知道是否为分支),因此需要使用BTB提高指令传送带宽。同时高级的前瞻技术能够进一步增强ILP。

提高取值带宽

分支目标缓冲BTB

预测尚未译码的指令是否为分支,如果是分支,则下一个PC是什么,这样能够将分支的代价将为0。分支预测缓存中存储着下一条指令的预取地址,这就是分支目标缓冲BTB。

BTB将分支成功的分支指令的地址和它的分支目标地址都放到一个缓冲区中保存起来,缓冲区以分支指令的地址作为标识;取指令阶段,所有指令地址都与保存的标识作比较,一旦相同,就认为本指令为分支指令,且让那位它转移成功,且它的分支目标(下一条指令)地址就是保存在缓冲区中的分支目标地址。

BTB工作流程如下

这里需要厘清分支预测缓冲BPB(分支预测器)和分支目标缓冲BTB的区别:

  • 相同点:都是解决控制相关的动态分支预测技术,其有两种目标:预测转移是否成功和尽早得到转移目标地址。

  • 不同点

  • 分支预测缓冲基于分支操作历史记录预测现在分支是否跳转(在译码阶段,所以还是得有延迟槽)

  • 分支目标缓冲直接在取指阶段判断是否为分支,如是则下一个PC应该是什么,延迟更少,特别适用于多发射处理器;

BTB的变体是存储一个或多个目标指令,作为预测目标地址的补充或代替,有两个好处:

  • 允许分支目标缓冲访问时间长于两个以上取指周期,从而可以吧BTB做的更大;

  • 实际上每条指令都变成了分支指令(后面直接接的跳转后的指令)因此不需要单独的分支指令了,这样就可以实现分支折叠(branch folding)

返回地址预测器

前面都是解决的直接跳转,而间接跳转需要访问寄存器,主要来源于return操作。尽管return能够使用BTB,但是准确率低(依靠PC判断,而函数可以从多个地方调用,一个地方多次调用的情况很少)。

为了解决这个问题,可以设计一个小型缓冲,类似于一个栈,存储最近的返回地址,函数调用时压栈,返回时弹栈,就能够准确预测return操作。(这也是为什么要避免递归,尽量使用循环)

集成取值单元

由于多发射的复杂性,不能再将取值当作一个简单的流水级了,需要一个专门的取值单元。主要功能如下

  • 分支预测:变成取值的一部分了

  • 指令预取:提前取指令以供每周期发射多条指令,和分支预测配合

  • 指令存储器访问与缓存:使用预取隐藏跨缓存模块的成本,并提供缓存,按需向发射单元提供相应数量的指令;

前瞻:问题与拓展

前瞻(Speculation)技术允许在处理器还未判断指令是否能执行之前就提前执行,以克服控制相关,实现前瞻的关键思想是:允许指令乱序执行,但必须顺序确认。加入指令确认阶段需要一套额外的硬件缓冲来保存那些执行完毕但未经确认的指令及其结果,称为重排序缓冲(Reorder Buffer,ROB),它同时还用来在前瞻执行的指令之间传送结果。

前瞻支持:寄存器重命名和重排序缓冲

ROB方法需要维护保留站、ROB、体系结构寄存器三个数据结构,造成寄存器资源浪费(一个值存在多个地方),因此进一步使用寄存器重命名,明确使用更大的物理寄存器集(体系结构寄存器是物理寄存器的子集),通过维护重命名表指出两者的对应关系即可。拓展后的寄存器取代了ROB和保留站的大部分功能,只需要一个队列来确保顺序完成指令即可。

指令发射时,将体系结构寄存器重命名为物理寄存器,为目的分配一个新的寄存器,因此WAW和WAR都可以通过寄存器重命名来解决。指令提交之前,保存指令目的的物理寄存器不会成为体系结构寄存器,解决了恢复的问题。指令提交时重命名表被更新,用于指示一个物理寄存器和体系结构寄存器对应,完成对处理器状态的更新。

何时撤销寄存器分配会比较复杂,只有当该物理寄存器不在于体系结构寄存器相对应,且后续指令不会用到才可以释放。两种方法

  1. 处理器通过查看功能单元队列中所有指令的源寄存器说明符,如果没有使用该物理寄存器且该物理寄存器不与体系结构寄存器对应,就可以回收;

  2. 处理器一直等待,知道对同一体系结构处理器执行写操作的另一指令提交。

比如:

add x1, x2, x3 # x1->p1
...
sub x1, x3, x4 # p1释放

当一个进程必须知道特定体系结构寄存器的内容时(如操作系统),可以一段时间不发射指令,让体系结构寄存器和物理寄存器映射关系稳定下来,再查看。

寄存器重命名的多发射策略

  1. 为整个指令包预留物理寄存器(4条指令最多4个)

  2. 判断包中存在的相关

  3. 如果包中指令依赖于之前的指令,则使用存放结果的物理寄存器更新指令发射信息

前瞻的代价

前瞻的重要优势就是尽早发现使流水线停顿的事件如cache miss,但是如果前瞻导致代价很大的事件如TLB miss就会得不偿失,因此只用前瞻模式处理低成本异常,如L1 cache miss。

多分支前瞻

三种情况可以通过同时推测多个分支获益

  1. 分支频率高

  2. 分支高度聚集

  3. 功能单元延迟长

能耗挑战

  1. 前瞻执行了却不需要该结果

  2. 撤销前瞻并恢复处理器状态

值预测

尝试预测一条指令可能产生的值,但成功率很有限,仅对一些特定的指令会比较好(从常数池中取值)。

 

相关讲解:第4章 指令级并行 - 知乎 (zhihu.com)