2012-09-13 20 views
5

以下のようなコードでは、コンパイラはaが実際にBのインスタンスであり、仮想テーブルの参照を最適化すると伝えることができますか? Jonthanセンとreimaの解答後に仮想テーブルの参照の最適化

#include <iostream> 

class A 
{ 
    public: 
    virtual void f() 
    { 
     std::cout << "A::f()" << std::endl; 
    } 
}; 

class B : public A 
{ 
    public: 
    void f() 
    { 
     std::cout << "B::f()" << std::endl; 
    } 
}; 

int main() 
{ 
    B b; 
    A* a = &b; 
    a->f(); 

    return 0; 
} 

追加質問:GCCが使用されている場合は、vtableの検索を最適化するために、それを強制するために、任意のフラグを使用する必要でしょうか?

+0

確実に見つけるための唯一の方法は、アセンブリを見ることです。しかし、はい、devirtualizationは標準コンパイラの最適化です。 – Mysticial

+0

GCCの分解を追加しました。私は基本的な最適化のために '-O1'フラグを使いました。 – reima

答えて

5

Clangこの最適化を簡単に行うことができ、さらに関数呼び出しをインライン化することもできます。これは、生成されたアセンブリから見ることができます。

Dump of assembler code for function main(): 
    0x0000000000400500 <+0>: push %rbp 
    0x0000000000400501 <+1>: mov %rsp,%rbp 
    0x0000000000400504 <+4>: mov $0x40060c,%edi 
    0x0000000000400509 <+9>: xor %al,%al 
    0x000000000040050b <+11>: callq 0x4003f0 <[email protected]> 
    0x0000000000400510 <+16>: xor %eax,%eax 
    0x0000000000400512 <+18>: pop %rbp 
    0x0000000000400513 <+19>: retq 

これが大幅に解体に混乱を減らすように私は、printfと同等の呼び出しによってstd::cout << …の交換の自由を取りました。

GCC 4.6はまた、何のvtableのルックアップが必要とされていないことを推測することができますが、インライン化されていません。

Dump of assembler code for function main(): 
    0x0000000000400560 <+0>: sub $0x18,%rsp 
    0x0000000000400564 <+4>: mov %rsp,%rdi 
    0x0000000000400567 <+7>: movq $0x4007c0,(%rsp) 
    0x000000000040056f <+15>: callq 0x400680 <B::f()> 
    0x0000000000400574 <+20>: xor %eax,%eax 
    0x0000000000400576 <+22>: add $0x18,%rsp 
    0x000000000040057a <+26>: retq 
+0

+1 Visual Studio 2010もまたそれを解体します。しかしそれはそれをインラインにしません。 – Mysticial

+0

私は現在gcc 4.4しか持っていません。それも、-O3で検索を最適化していないよう: SUBQ \t $ 24%のRSP は32 MOVQ \t $ _ZTV1B + 16、(%のRSP) MOVQ \t%のRSP、%のRDI コール\t * _ZTV1Bを.cfi_def_cfa_offset 16(%リッピング) xorl \t% eaxに、%eaxに ADDQ \t $ 24%RSP .cfi_def_cfa_offset 8 RET – Ruup

+1

ネジに!ちょうどそれをフォーマットすることはできません! – Ruup

-2

おそらく、それはコンパイラの最適化と最適化の必要条件に依存します。

しかし、これは1回の呼び出しです。なぜこの1つのコールを最適化したいのですか?あなたが気にしているのであれば、この1通話のタイプ権を得るだけではどうですか?

最適化に関するすべての質問の最初の答えは、「なぜそれを最適化する必要がありますか?」です。アプリケーション時間の50%が1つの場所であることを示すパフォーマンスツールレポートを用意して、質問に答えます。最も一般的な答えである「ああ、その非効率的なもの」は、コードが実際には効率が悪いものをほとんど最適化しない、維持できないコードにつながります。

+1

私はダウンボートをしなかったが、OPが気にしなかったなら、この質問は聞かれなかっただろう。 – Mysticial

+2

理由がない場合、人は最適化を気にすることがよくあります。だから、私はそれから質問をするつもりです。 –

+0

その答えはコメントに書かれているはずです。 –

関連する問題