什么是软件流水线?
软件流水线是一种编译时调度技术,它重叠后续循环迭代以公开操作级并行性。开发足够的软件流水线算法的一个必要问题是如何处理包含条件分支的循环。条件分支通过提供少量可能的执行路径到调度机会,增加了复杂性并降低了软件流水线算法的性能。
为了演示其基本思想,让我们看一下在具有多个并行操作执行单元的ILP处理器上循环的最可行的并行执行。让我们假设循环体采用类似RISC的中间代码,例如:
load r100, b(i); fmul r100, 2.0, r100; store a(i), r100;
在演示软件流水线的原理时,我们只关注循环体,忽略一些序言和结语代码。
它可以对ILP处理器做出以下假设:它具有独立的FP、FX、加载和存储指令执行单元,所有这些单元都能够并行操作。所有执行单元都应允许每个周期启动一个新操作。最后,我们假设FP单元在例如三个周期内提供fmul指令的结果,而加载和存储的执行延迟为一个周期。
现在让我们寻找最可行的并行执行。当我们尽可能并行地展开循环和后续迭代时,就可以实现它。让我们从第一次迭代开始。它可以按如下方式执行:
周期 | 指令 | 注释 |
---|---|---|
c | load r101, b(1); | // 加载 b(1) |
c+1 | fmul r101, 2.0, r101, | |
c+2 | decr r200; | // 递减循环计数 |
c+3 | Nop | // 等待fmul的结果 |
c+4 | store a(i) +, r101; | // 存储 a(i),自动递增 i。 |
在这里,我们注意到假设的最终操作延迟为三个周期,因此在周期 c + 3 中其结果尚未可用,并且必须插入“nop”。根据所做的假设,可以通过加载第二个数据项 b(2) 在周期 c+1 中启动第二次迭代。
它可以避免与第一次迭代的干扰,即避免在第二次迭代中使用 r101 的WAW冲突,r101必须重命名,例如为 r102。随后,两次迭代可以并行实现。这可以接收以下执行序列:
周期 | 1.迭代 | 2.迭代 |
---|---|---|
c | load r101, b(1); | |
c+1 | fmul r101, 2.0, r101, | load r102, b(2); |
c+2 r102, | decr | fmul r102, 2.0, |
c+3 | Nop | Decr |
c+4 | store a(i) +, r101; | Nop |
c+5 | store a(2) +, r102; |
在下表中,它可以显示循环的整个执行过程。让我们看看周期 c+4、c+5 和 c+6。这些周期显示了软件流水线的真正优势。重要的是,对于这些周期,后续循环迭代之间的可用并行性得到了充分利用。例如,在周期 c+4 中,并行操作如下:
它可以存储迭代 1 的结果(即 a(1)),自动递增索引。
它可以将由 r200 保持的循环计数递减 1。
它可以使用属于周期 4 的操作数执行浮点乘法,即 (2.0 * b(4));
它可以加载迭代 5 的操作数,即 b(5)。
在具有多个流水线执行单元的ILP处理器上给定循环的最并行执行
周期 | 迭代编号 | ||||||
---|---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 | |
c | load | ||||||
c+1 | fmul | load | |||||
c+2 | decr | fmul | Load | ||||
c+3 | nop | decr | fmul | Load | |||
c+4 | store | Nop | Decr | Fmul | load | ||
c+5 | store | Nop | Decr | fmul | load | ||
c+6 | store | Nop | decr | fmul | Load | ||
c+7 | store | nop | decr | fmul | |||
c+8 | store | nop | Decr | ||||
c+9 | store | Nop | |||||
c+10 | store |