仮想関数テーブル 多重継承とthunk

仮想関数テーブル

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2023/11/25 17:30 UTC 版)

多重継承とthunk

g++ コンパイラはクラス DB1B2 からの多重継承を、基底クラスごとに一つずつの、二つの仮想関数テーブルを用いて実現する(多重継承を実現するには他にも方法があるがこれが最も一般的である)。これにより、キャストの際 "pointer fixups" (thunk) が必要になる。

下記のような C++ コードを考える:

D  *d  = new D();
B1 *b1 = dynamic_cast<B1*>(d);
B2 *b2 = dynamic_cast<B2*>(d);

db1 が実行時に同じメモリ位置を参照するが、 b2d+8d のメモリ配置の8バイト後方)を示す。 そのため、b2d 内の B2 らしく見える領域、 すなわち B2 のインスタンスと同じメモリレイアウトを持つ部分を示す。

呼び出し

呼び出しの際には、d->f1() の呼び出しの際は、dD::B1 vpointer をたどり、vtable から f1 のエントリーを調べ、ポインタを取り出してコードを呼び出す。

単一継承(あるいは、単一継承のみ可能な言語)の場合、vpointer が常に d の最初の要素にあれば(多数のコンパイラでそうなっている)、下記のような擬似 C++ のコードに簡略化できる。

*((*d)[0])(d)

より一般的なケースでは、上記のようなdf1()D::f2()B2::f2() 呼び出しはより複雑なものとなる。

*((d->/* Dの(B1用の)仮想関数テーブルへのポインタ*/)[0])(d)
*((d->/* Dの(B1用の)仮想関数テーブルへのポインタ*/)[12])(d)
*((d->/* Dの(B2用の)仮想関数テーブルへのポインタ*/)[0])(d+8)

これに対して、d->f0() の呼び出しはもっと単純である:

*B1::f0(d)

効率

単なるコンパイルされたポインタへのジャンプである非仮想関数の呼び出しに対して、仮想関数の呼び出しは最低一度以上、余分にポインタをたどる操作や"fixup" が必要である。そのため、仮想関数の呼び出しは原理的に非仮想の関数呼び出しに対して低速である。実験によれば 6-13% の実行時間が単なる関数のディスパッチに用いられ、オーバーヘッドは場合によって 50% に達する[1]

さらに、 JIT コンパイルが使用できない環境では、仮想関数は通常インライン展開できない。テーブルの参照を行う部分を、たとえばインライン化された本体部分を条件文で実行させることも可能ではあるが、そうした最適化は一般的ではない。

オーバーヘッドを避けるため、コンパイラはコンパイル時に呼び出しが解決できる場合には vtable の生成を行わない。

従って、上記の f1 の呼び出しは、 d が現時点で D のみ保持しており、Df1 をオーバーライドしないことをコンパイラが判断できるため、vtable の検索は必要なくなる可能性がある。コンパイラ(あるいは最適化プログラム)はプログラム内に f1 をオーバーライドする B1 のサブクラスがないことを検出することができるかもしれない。実装が明示的に指定されているため(this ポインタの fixup が必要ではあるが)B1::f1 または B2::f2 はおそらく vtable の検索を必要とすることはない。


注釈

  1. ^ g++ の -fdump-class-hierarchy オプションで、仮想関数テーブルを出力して手動でチェックすることができる。
  2. ^ AIX の VisualAge XlC コンパイラでは -qdump_class_hierarchy を用いてクラスの階層構造と仮想関数テーブルのレイアウトを出力することができる。

出典

  1. ^ Driesen, Karel and Holzle, Urs, "The Direct Cost of Virtual Function Calls in C++", OOPSLA 1996
  2. ^ Zendra, Olivier and Driesen, Karel, Stress-testing Control Structures for Dynamic Dispatch in Java", Pp. 105?118, Proceedings of the USENIX 2nd Java Virtual Machine Research and Technology Symposium, 2002 (JVM '02)


「仮想関数テーブル」の続きの解説一覧



英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「仮想関数テーブル」の関連用語

仮想関数テーブルのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



仮想関数テーブルのページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアの仮想関数テーブル (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。

©2024 GRAS Group, Inc.RSS