乱序执行

乱序执行的目的就是尽可能的防止分发停顿,比如真正的写后读相关时,流水线必须停顿。思路就是让相关的指令离独立的指令远一点。

乱序执行的条件

  1. 需要在值的生产者和消费者之间建立通信,这里消费者指的是当前这条指令,生产者指的是在与这条指令相关的指令。

    • 寄存器重命名:给每个值一个tag。
  2. 需要给指令提供缓冲区。

    • 保留站。
  3. 指令需要持续监测值是否可用。

    • 当这个值准备好了,就广播自己的tag,消费者匹配tag,如果是自己用的,就知道这个值已经准备好了。
  4. 当全部的值都准备好,需要分发指令到对应的功能单元上去。

    • 需要的全部值都准备好,分发指令,出保留站。

寄存器重命名

Tomasulo算法

历史

由Robert Tomasulo发明了带寄存器重命名的乱序执行,用于IBM 360/91的浮点运算单元,需要注意的是当时的IBM 360/91并不支持精确异常,所以我们现在所说的Tomasulo算法与当时的方法还是存在区别。最早商用是在因特尔奔腾Pro。

今天几乎全部主流处理器使用的乱序执行算法都是Tomasulo算法的变种。

指令执行规模受限于指令窗口。

步骤

如果保留站在重命名之前可用,那么将指令和操作数(值+tag)插入保留站。

在保留站中,每条指令关注公共数据总线(CDB)上的数据的tag,看到自己用的tag,就获取数据并保存在保留站,知道全部操作数可用,进行指令分发。

那么指令在功能单元中完成操作后,进行CDB仲裁,将打了tag的值送到CDB上,寄存器堆也连接CDB,如果寄存器的tag(标记了最近需要写入寄存器的entry)与广播的tag匹配,将广播的值存入寄存器,并置有效位,同时回收重命名的tag。

下面是一些例子:

非精确异常的无转发:

非精确异常的全转发:

非精确异常的Tomasulo+全转发:

具体实现借助了寄存器重命名表(寄存器别名表RAT),接下来我们手推一下Tomasulo的过程。

保留站

相关指令的“休息区”,直到数据准备好才出来。这就需要时刻监控保留站中每条指令使用的值,也就是说指令是按照数据流的顺序分发的。与精确异常中的ROB之类的方法不同,这里的乱序指的是乱序分发,而精确异常中指的乱序,意思是乱序执行,但是顺序分发,顺序回收。

好处:容忍延迟(允许独立指令在长时延操作时执行和完成),可以连续的取指译码。

可以看下面的例子:

乱序执行的概念小结

寄存器重命名消除了虚假的相关,建立了生产者和消费者的关系。

保留站使得流水线可以执行独立的操作以保持流水。

标签广播是的指令之间能够交互生产出的值。

唤醒和选择保证了乱序执行的分发。

乱序执行实际上是构建了一个程序块的数据流图,而数据流受限于指令窗口(ROB),简单来说就是在这部分代码段上可以乱序执行,虽然是乱序执行,但是保证了ISA顺序的要求,乱序执行仅仅被约束在微体系结构层面。

posted @ 2020-08-02 14:49  xinze  阅读(1660)  评论(0编辑  收藏  举报