[英]C++ Does the compiler optimize out known statements?
This question no doubt would constitute premature optimization, however I want to know what the compiler will do with this to learn more about how the compiler works.这个问题无疑会构成过早的优化,但是我想知道编译器将对此做什么,以了解更多关于编译器如何工作的信息。
In the below example, can I expect the compiler to produce 2 or 3 functions with the if
statements removed, or is it always going to execute that if
statement on every iteration of the loop?在下面的示例中,我是否可以期望编译器在删除
if
语句的情况下生成 2 或 3 个函数,或者它是否总是会在循环的每次迭代中执行该if
语句? Is the compiler going to optimize out the if
statement on the basis that the function is called only with a parameter that is known at compile time?编译器是否会在仅使用编译时已知的参数调用 function 的基础上优化
if
语句?
void myfunction(int a) {
for (int i = 0; i < 1000000; ++i) {
// here are various calculations that are the same regardless of a
if (a == 0) {
dosomething1(someValue);
} else if (a == 1) {
dosomething2(someValue);
} else {
dosomething3(someValue);
}
}
}
myfunction(0);
myfunction(1);
This depends entirely on the compiler and optimization level.这完全取决于编译器和优化级别。
For example, GCC 10 will transform loops to hoist invariants out at -O3 level.例如,GCC 10 将转换循环以在-O3级别提升不变量。 We can see in this demo ( Godbolt link ) that it generated 3 separate loops essentially:
我们可以在这个演示( Godbolt 链接)中看到它本质上生成了 3 个独立的循环:
myfunction(int):
push rbp
push rbx
mov ebx, edi
sub rsp, 8
test edi, edi
je .L2
cmp edi, 1
je .L6
xor ebp, ebp
.L4:
mov edi, ebx
xor edi, ebp
add ebp, 1
call dosomething3(int)
cmp ebp, 1000000
jne .L4
.L1:
add rsp, 8
pop rbx
pop rbp
ret
.L2:
mov edi, ebx
add ebx, 1
call dosomething1(int)
cmp ebx, 1000000
jne .L2
jmp .L1
.L6:
xor ebx, ebx
.L3:
mov edi, ebx
add ebx, 1
xor edi, 1
call dosomething2(int)
cmp ebx, 1000000
jne .L3
add rsp, 8
pop rbx
pop rbp
ret
But at -O2 level the checks on a
are inside the loop:但是在-O2级别,对
a
的检查在循环内:
myfunction(int):
push rbp
mov ebp, edi
push rbx
xor ebx, ebx
sub rsp, 8
jmp .L5
.L2:
mov edi, ebp
xor edi, ebx
cmp ebp, 1
je .L9
call dosomething3(int)
.L3:
add ebx, 1
cmp ebx, 1000000
je .L10
.L5:
test ebp, ebp
jne .L2
mov edi, ebx
add ebx, 1
call dosomething1(int)
cmp ebx, 1000000
jne .L5
.L10:
add rsp, 8
pop rbx
pop rbp
ret
.L9:
call dosomething2(int)
jmp .L3
So you'd have to check how your specific compiler handles this.所以你必须检查你的特定编译器是如何处理这个的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.