2017-01-09 50 views
6

如果您有布爾值b和int i,那麼這兩個示例中的哪一個更好?基於布爾C++確定數值的最快方法

int x = i-1; 
if(!b)x--; 

int x; 
if(b)x = i-1;else x = i-2; 

在這兩個例子中,如果b是真的xi-1,否則xi-2。如果您宣佈xi-1,並且如果b錯誤或者您應該使用第二個示例,則應該遞減?

+9

無分支版本是'x = i-2 + b;' –

+4

如果你在發行版中編譯,編譯器會輸出相同的代碼 – user

+1

爲什麼你要問?微觀優化是無關緊要的。 –

回答

10

如果編譯器沒有將兩個版本都優化到相同的最佳程序集,我會感到驚訝。除非您可以使用探查器證明它們的重要性,否則不要浪費時間進行這種微觀優化。

要回答你的問題:這是無關緊要的。以下是gcc.godbolt.org-Ofast的「生成裝配」比較。


volatile int state0; 
volatile void f0(volatile int i, volatile bool b) 
{ 
    int x; 
    if(b)x = i-1;else x = i-2; 
    state0 = x; 
} 

...被編譯到...

f0(int, bool):        # @f0(int, bool) 
     mov  dword ptr [rsp - 4], edi 
     mov  byte ptr [rsp - 5], sil 
     movzx eax, byte ptr [rsp - 5] 
     or  eax, -2 
     add  eax, dword ptr [rsp - 4] 
     mov  dword ptr [rip + state0], eax 
     ret 

volatile int state1; 
volatile void f1(volatile int i, volatile bool b) 
{ 
    int x = i-1; 
    if(!b)x--; 
    state1 = x; 
} 

...被編譯到...

f1(int, bool):        # @f1(int, bool) 
     mov  dword ptr [rsp - 4], edi 
     mov  byte ptr [rsp - 5], sil 
     mov  eax, dword ptr [rsp - 4] 
     movzx ecx, byte ptr [rsp - 5] 
     or  ecx, -2 
     add  ecx, eax 
     mov  dword ptr [rip + state1], ecx 
     ret 

正如您所看到的,差異很小,而且通過刪除volatile,允許編譯器更積極地進行優化時,極有可能會消失。


這裏有一個類似的比較以圖片形式,使用-Ofast -march=native -ffast-math

Godbolt comparison

+0

請提一下你使用了哪些標誌(-O3?) –

+0

@IvanRubinson:它位於godbolt鏈接上,我使用了'-Ofast'。 –

+0

謝謝!我只是因爲好奇而問。 – theo2003

5

檢查彙編代碼,因爲優化將優化,可能是爲了相同的解決方案既您的解決方案。

我可能會實現它:

int x = (b) ? i - 1 : i - 2; 

出於可讀性和高可能的優化將使其等於爲你的第二個解決方案。

+3

我會寫'int x = i - b? 1:2;'不要提'i'兩次 – Slava

+1

我會寫'const int x = i - 2 + !! b',以免有任何分支。 –

+0

'int x = i - 2 + b'會起作用嗎? – theo2003