多条指令发射
为了使流水线的CPI更好(更小)于1,并更好地利用指令级并行性(ILP),必须在同一流水线周期中发出多个独立的指令。
两种类型:
- 超标量:在同一周期内发出多条指令(2-8条),由编译器静态调度或动态调度(Tomasulo)。
- 超长指令字:固定数量的指令(3-6)被格式化为一个长指令字或包(由编译器静态调度)。
静态调度超标量流水线
每个周期可以发出两条指令(two-issue超标量)。其中一个指令是integer(包括load/store,branch)。另一条指令是浮点运算。
超长指令字
超标量流水线动态调度
对Tomasulo动态调度算法进行了扩展,使其每个周期发出多条指令。然而,指令必须按程序顺序发出的限制仍然有效,以避免违反指令依赖关系。在一个周期内发出多条指令的结果应该与单次发出相同。
如何为Tomasulo发出两个指令并保持按顺序发出指令?
最简单的方法:限制每个周期发出的指令类型
为了简化发出逻辑,每个周期发出一个整数+一个浮点指令。
1个Tomasulo控件用于整数,1个用于浮点。
只有FP加载可能导致整数和FP问题之间的依赖性:
- 用负载队列代替负载预留站;操作数必须按照取数的顺序读取。
- 加载检查存储队列中的地址以避免原始冲突
- 存储检查加载队列中的地址,以避免WAR,WAW。
在Tomasulo中可以使用三种技术来支持多指令发布
在不限制每个周期发出的指令类型的情况下:
-
以更高的时钟速率发出,使发出保持正常。
-
扩展发布逻辑以处理多指令发布
-
一次检测要发出的指令之间的所有可能的依赖关系,并且多个发出的结果匹配顺序发出
为了避免在最后两种方法中增加CPU时钟周期时间,可以将多指令发出分为两个流水线发出阶段:
- 发射阶段一:决定可以同时发布多少条指令,检查要发布的指令组中的依赖关系,忽略已经发布的指令。
- 发射阶段二:检查来自小组的选定指令和已经发布的指令中的危险。
这种方法通常用于动态调度的宽超标量,这些超标量每个周期可以发出四条或更多指令。
将问题分成两个流水线分段会增加CPU流水线深度并增加分支损失。
超标量的动态调度控制逻辑通常是非常复杂的,至少随问题宽度呈二次增长。
多条指令发射的挑战
虽然两个问题的单个Integer/FP拆分在硬件上很简单,但只有在以下情况下,我们才会得到0.5的CPI:
- 正好50%的FP操作
- 没有任何类型的竞争。
如果同时发出更多指令,则产生更大的解码和发出操作的困难
多发射技术的局限性
如果每5条指令都有一个分支:如何保持5路VLIW繁忙?
单元的延迟增加了每个周期必须调度的许多操作的复杂性。