2012-12-10 47 views
2

假設編譯器事實上是inline foo這兩個語句之間是否存在性能差異?C++內聯函數可以防止複製嗎?

inline int foo (int val) { 
    return val; 
} 

int main() { 

    std::cout << foo(123) << std::endl; 

    std::cout << 123 << std::endl; 

    return 0; 
} 

讓我們忽略移動語義和複製elision可能有的任何影響。

+0

你爲什麼不測量它 – pm100

+3

他們看起來和我一樣。你可以看看生產的組件來驗證。 –

回答

4

我的編譯器(gcc 4.7.2)產生幾乎相同的代碼爲兩個語句:

_main: 
LFB1018: 
     pushq %rbx 
LCFI0: 
     movq [email protected](%rip), %rbx 

; std::cout << foo(123) << std::endl; 
     movl $123, %esi 
     movq %rbx, %rdi 
     call __ZNSolsEi 
     movq %rax, %rdi 
     call __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ 

; std::cout << 123 << std::endl; 
     movq %rbx, %rdi 
     movl $123, %esi 
     call __ZNSolsEi 
     movq %rax, %rdi 
     call __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ 

     xorl %eax, %eax 
     popq %rbx 
LCFI1: 
     ret 

唯一的區別是前兩個指令的順序。我已經嘗試過了,這種差異似乎與foo()沒有任何關係:如果我重複這兩行兩次,只有四條語句中的最後一條將指令順序顛倒過來。這使我認爲這個工件可能與流水線優化器或某種性質有關。

+0

它確實交換了前兩條指令;任何想法爲什麼?否則他們是平等的。 –

+0

@JanDvorak:我一直在想這個。 – NPE

+0

爲什麼要保存'%rbx'? –

1

應該絕對是一樣的。

爲了確保它確實如此,請使用gcc中的-S標誌生成彙編代碼並手動比較兩行。

另外,請注意,內聯關鍵字只是編譯器的提示,編譯器可能會選擇忽略它。 This question對使用​​內聯進行了深入的討論。

相關問題