流水线处理器如何处理过度展开的循环?
How does a pipelined processor handle excessively unrolled loops?
假设
for (int i = 0; i < N; ++i) {
sum += nums[i];
}
被编译器展开成类似于
的东西
for (int i = 0; i < N; i += 4) {
sum1 += data[i];
sum2 += data[i+1];
sum3 += data[i+2];
sum4 += data[i+3];
}
sum = sum1 + sum2 + sum3 + sum4;
如果循环展开超出它们应该展开的范围会怎样?例如,如果 N
是 101,那么 i
将在某个时候为 100,但索引 101、102、103 超出了数组的边界。
也许我们希望在展开和计算循环结束时像往常一样保守——但即便如此,如果确定了迭代次数,那么保守地猜测循环可以展开多少来自哪里在运行时?
Pete 关于代码缺少最后 3 个元素的说法是正确的。关于您关于管道的问题...
流水线处理器有严重的分支惩罚,它们不喜欢过于紧凑的循环。在汇编级别,流水线处理器可以访问重复单条指令和重复块指令。
在高级语言中,展开可以由编译器或开发人员执行。在您列出的代码中,开发人员代码每个周期执行 4 次求和。
假设
for (int i = 0; i < N; ++i) {
sum += nums[i];
}
被编译器展开成类似于
的东西for (int i = 0; i < N; i += 4) {
sum1 += data[i];
sum2 += data[i+1];
sum3 += data[i+2];
sum4 += data[i+3];
}
sum = sum1 + sum2 + sum3 + sum4;
如果循环展开超出它们应该展开的范围会怎样?例如,如果 N
是 101,那么 i
将在某个时候为 100,但索引 101、102、103 超出了数组的边界。
也许我们希望在展开和计算循环结束时像往常一样保守——但即便如此,如果确定了迭代次数,那么保守地猜测循环可以展开多少来自哪里在运行时?
Pete 关于代码缺少最后 3 个元素的说法是正确的。关于您关于管道的问题...
流水线处理器有严重的分支惩罚,它们不喜欢过于紧凑的循环。在汇编级别,流水线处理器可以访问重复单条指令和重复块指令。
在高级语言中,展开可以由编译器或开发人员执行。在您列出的代码中,开发人员代码每个周期执行 4 次求和。