流水线处理器如何处理过度展开的循环?

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 次求和。