C++ 编译器会使用少量术语内联 for 循环吗?
Will a C++ compiler inline a for-loop with a small number of terms?
假设我有一个 class Matrix5x5
(具有适当重载的索引运算符)并且我编写了一个方法 trace
来计算其对角线元素的总和:
double Matrix5x5::trace(void){
double t(0.0);
for(int i(0); i <= 4; ++i){
t += (*this)[i][i];
}
return t;
}
当然,如果我改写:
return (*this)[0][0]+(*this)[1][1]+(*this)[2][2]+(*this)[3][3]+(*this)[4][4];
那么我一定会避免声明和递增我的 i
变量的开销。但是写出所有这些条款感觉很愚蠢!
由于我的循环有 constexpr
个恰好很小的项,编译器会为我内联它吗?
如果您的编译器足够聪明,它可以使用 as-if rule 优化这种情况。 C++ 编译器可能会以这种方式优化很多东西。但它也可能不会。唯一可以绝对确定的方法是检查特定编译器生成的代码。话虽如此,这不太可能成为您程序中的瓶颈。所以无论哪个版本更具可读性。
是的! GCC 在优化级别 -O1
及以上执行,而 clang 在优化级别 -O2
及以上执行。
我用这段代码测试了它:
struct Matrix5x5 {
double values[5][5];
Matrix5x5() : values() {}
double trace() {
double sum = 0.0;
for(int i = 0; i < 5; i++) {
sum += values[i][i];
}
return sum;
}
};
double trace_of(Matrix5x5& m) {
return m.trace();
}
这是 gcc 和 clang 生成的程序集:
trace_of(Matrix5x5&):
pxor xmm0, xmm0
addsd xmm0, QWORD PTR [rdi]
addsd xmm0, QWORD PTR [rdi+48]
addsd xmm0, QWORD PTR [rdi+96]
addsd xmm0, QWORD PTR [rdi+144]
addsd xmm0, QWORD PTR [rdi+192]
ret
您可以尝试一下代码,并在此处查看相应的程序集:https://godbolt.org/z/p2uF0E。
如果重载 operator[]
,则必须将优化级别提高到 -O3
,但编译器仍会这样做:https://godbolt.org/z/JInIME
假设我有一个 class Matrix5x5
(具有适当重载的索引运算符)并且我编写了一个方法 trace
来计算其对角线元素的总和:
double Matrix5x5::trace(void){
double t(0.0);
for(int i(0); i <= 4; ++i){
t += (*this)[i][i];
}
return t;
}
当然,如果我改写:
return (*this)[0][0]+(*this)[1][1]+(*this)[2][2]+(*this)[3][3]+(*this)[4][4];
那么我一定会避免声明和递增我的 i
变量的开销。但是写出所有这些条款感觉很愚蠢!
由于我的循环有 constexpr
个恰好很小的项,编译器会为我内联它吗?
如果您的编译器足够聪明,它可以使用 as-if rule 优化这种情况。 C++ 编译器可能会以这种方式优化很多东西。但它也可能不会。唯一可以绝对确定的方法是检查特定编译器生成的代码。话虽如此,这不太可能成为您程序中的瓶颈。所以无论哪个版本更具可读性。
是的! GCC 在优化级别 -O1
及以上执行,而 clang 在优化级别 -O2
及以上执行。
我用这段代码测试了它:
struct Matrix5x5 {
double values[5][5];
Matrix5x5() : values() {}
double trace() {
double sum = 0.0;
for(int i = 0; i < 5; i++) {
sum += values[i][i];
}
return sum;
}
};
double trace_of(Matrix5x5& m) {
return m.trace();
}
这是 gcc 和 clang 生成的程序集:
trace_of(Matrix5x5&):
pxor xmm0, xmm0
addsd xmm0, QWORD PTR [rdi]
addsd xmm0, QWORD PTR [rdi+48]
addsd xmm0, QWORD PTR [rdi+96]
addsd xmm0, QWORD PTR [rdi+144]
addsd xmm0, QWORD PTR [rdi+192]
ret
您可以尝试一下代码,并在此处查看相应的程序集:https://godbolt.org/z/p2uF0E。
如果重载 operator[]
,则必须将优化级别提高到 -O3
,但编译器仍会这样做:https://godbolt.org/z/JInIME