浮点运算中的数据冒险与Tomasula算法优化
1. 浮点指令中的数据冒险问题
在浮点指令执行过程中,会出现多种数据冒险问题,主要包括写后读(RAW)、读后写(WAR)和写后写(WAW)冒险。
1.1 WAR冒险示例
在一个程序中,ADDF和SUBF指令之间存在WAR冒险。SUBF指令在第5个时钟周期写入F8的内容,而更早的ADDF指令在第12个时钟周期尝试使用该操作数。因此,ADDF指令很可能读取到的是SUBF指令写入F8的内容,而不是更早指令写入的内容。
1.2 WAW冒险示例
ADDF和MULF指令之间存在WAW冒险。MULF指令在第10个时钟周期写入F6的内容,而更早的ADDF指令在第13个时钟周期才写入相同的操作数,从而产生了这种冒险。
2. 乱序执行与寄存器重命名
如果按顺序执行浮点指令,可能需要相当多的时钟周期。通过故意延迟ADDF、SUBF和MULF指令的执行阶段,可以消除潜在的RAW、WAR和WAW冒险,并按顺序执行所有四条浮点指令,但这样会比原程序多增加6个时钟周期。
为了减少完成程序所需的时钟周期数,同时获得无冒险的指令执行流程,可以采用寄存器重命名的方法。在这种方法中,将ADDF和SUBF指令的目标寄存器分别重命名为X和Y,而不是原来的F6和F8。同时,将MULF指令的源寄存器改为Y,以便正确地将数据转发给该指令。这样,新程序只需要13个时钟周期,而不是原来的19个,并且消除了所有浮点冒险。
2.1 寄存器重命名消除冒险的原理
- 消除WAW冒险 :ADD