首先回顾一下tomasulo算法,
Tomasulo算法的第一个优点是分布式的冒险检测逻辑,这是通过使用预留站和公共数据总线实现的。预留站是一种存储指令和操作数的缓冲区,每个功能单元都有自己的预留站。公共数据总线是一种广播结果的方式,可以让多个预留站同时获取结果。如果有多个指令都在等待一个结果,并且每个指令都已经有了另一个操作数,那么当结果通过公共数据总线广播时,这些指令就可以同时开始执行。如果使用集中式的寄存器文件,那么功能单元就必须在寄存器总线可用时才能从寄存器读取结果。
Tomasulo算法的第二个优点是消除了WAW和WAR冒险,这是通过使用预留站重命名寄存器和把操作数尽早存入预留站实现的。WAW冒险是指后面的指令写入了前面的指令要写入的寄存器,WAR冒险是指后面的指令读取了前面的指令要写入的寄存器。在Tomasulo算法中,每个预留站都相当于一个临时寄存器,当一个指令被发射到预留站时,它就会被分配一个新的寄存器名字。同时,如果它需要的操作数已经准备好了,就会被复制到预留站中;如果还没有准备好,就会记录下提供操作数的预留站编号。这样,后面的指令就不会影响前面的指令的执行。
用三个表格展示了当fmul.d准备写入结果时,各个预留站和寄存器状态表的情况。在这个例子中,fadd.d已经完成了,因为fdiv.d需要的操作数被复制了,从而克服了WAR冒险。即使f6被fdiv.d占用了,fadd.d也可以执行并把结果写入f6,而不会触发WAW冒险。因为使用fdiv.d结果的指令会指向它对应的预留站编号,而不是直接使用f6。
注 上图为之前,下图为之后
在 Tomasulo 的方案中,结合了两种不同的技术:将架构寄存器重命名为更大的寄存器集以及缓冲寄存器文件中的源操作数。 源操作数缓冲解决了当操作数在寄存器中可用时出现的 WAR 危险。 正如我们稍后将看到的,还可以通过重命名寄存器并缓冲结果来消除 WAR 危险,直到不再保留对寄存器早期版本的未完成引用为止。
Tomasulo 的方案在 360/91 之后多年没有使用,但从 20 世纪 90 年代开始在多发行处理器中广泛采用,原因如下:
1.虽然Tomasulo的算法是在缓存之前设计的,但缓存的存在及其固有的不可预测的延迟已经成为动态调度的主要动机之一。 无序执行允许处理器在等待高速缓存未命中完成的同时继续执行指令,从而隐藏全部或部分高速缓存未命中损失。
2. 随着处理器的处理能力变得更加积极,并且设计人员关注难以调度的代码(例如大多数非数字代码)的性能,寄存器重命名、动态调度和推测等技术变得更加重要。
3.无需编译器将代码定位到特定的管道结构即可实现高性能,这在紧缩的大众市场软件时代是一个宝贵的特性。