繁体   English   中英

C++ 编译器是否优化了已知语句?

[英]C++ Does the compiler optimize out known statements?

这个问题无疑会构成过早的优化,但是我想知道编译器将对此做什么,以了解更多关于编译器如何工作的信息。

在下面的示例中,我是否可以期望编译器在删除if语句的情况下生成 2 或 3 个函数,或者它是否总是会在循环的每次迭代中执行该if语句? 编译器是否会在仅使用编译时已知的参数调用 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);

这完全取决于编译器和优化级别。

例如,GCC 10 将转换循环以在-O3级别提升不变量。 我们可以在这个演示( 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

但是在-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

所以你必须检查你的特定编译器是如何处理这个的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM