如果编译器可以内联任何一个函数,它也会展开循环,如果它认为这是正确的做法。编译器何时以及如何决定展开循环有好处是一个相当复杂的问题,并且高度取决于其他因素,例如可用寄存器的数量,循环内部发生的情况(我怀疑上面给出的示例,例如, 将从减少循环中涉及的 5 条左右指令中获得很多时间,因为这cout ...
可能会消耗数千倍的时间 - 编译器是否能解决这个问题是另一回事,但这并不是完全未知让编译器对函数是否小有一定的了解。
另一方面,如果代码看起来像这样:
int arr[N]; // Global array.
template<int N>
int fun()
{
int sum = 0;
for(int i = 0; i < N; ++i)
{
sum += arr[i];
}
}
然后我希望编译器展开循环是这样的:
int *tmp = arr;
sum += *tmp++;
sum += *tmp++;
sum += *tmp++;
sum += *tmp++;
sum += *tmp++;
假设 N = 5。
这适用于任何对编译器“可见”且 N 在编译时已知的函数。所以,假设gun
不在不同的源文件中,那么我希望它被内联和展开完全相同fun
(作为模板函数,必须在这个编译单元中可见)