簡體   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