3

コンパイラが実際にインライン化すると仮定すると、fooこれら 2 つのステートメントの間にパフォーマンスの違いはありますか?

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

int main () {

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

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

  return 0; 
}

移動セマンティクスとコピー省略が持つ可能性のある意味は無視しましょう。

4

2 に答える 2

5

私のコンパイラ (gcc 4.7.2) は、2 つのステートメントに対してほぼ同じコードを生成します。

_main:
LFB1018:
        pushq   %rbx
LCFI0:
        movq    __ZSt4cout@GOTPCREL(%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

唯一の違いは、最初の 2 つの命令の順序です。私はそれを試してみましたが、この違いは何の関係もないようですfoo().2行を2回繰り返すと、4つのステートメントの最後のステートメントだけが命令の順序が逆になります. これは、このアーティファクトがおそらくパイプライン オプティマイザまたはその性質に関係していると思わせます。

于 2012-12-10T18:42:36.310 に答える
1

は絶対に同じである必要があります。

それが実際に当てはまることを確認するには-S、gccのフラグを使用してアセンブリコードを生成し、2行を手動で比較します。

また、インラインキーワードはコンパイラへの単なるヒントであり、コンパイラはそれを無視することを選択する場合があることに注意してください。この質問には、インラインの使用に関する詳細な説明があります。

于 2012-12-10T18:43:20.197 に答える