0

C++ テンプレートがある場合、それらをリンクするには 2 つの選択肢 ( exportキーワードなし) があります。

  • インライン化による包含モデル - つまり、.h ファイル内の宣言と一緒に定義を組み込みます。これにより、すべての関数がインライン化され、大きなユニットが作成されます (怠け者ですが)。

  • インライン化なしの包含モデル - つまり、この .h ファイルを含めるようなもの:

コード:

// templateinstantiations.cpp
#include "array.cpp"
template class array <int, 50>; // explicit instantiation

テンプレートを使用するたびに、必要なすべての型を明示的にインスタンス化するように注意します (これは退屈で保守が難しい場合があります)。

私の質問は次のとおりです。関数を過度にインライン化すると、メモリのスラッシングとパフォーマンスの低下が発生する可能性があることを知っています..さらに、上記の両方のケースでコンパイル時間が膨大になるようです..最初と2番目のアプローチのトレードオフは何ですか? 2 番目よりも 1 番目を選択する基準はありますか、それとも、それらを試して「時間を計る」必要がありますか?

4

2 に答える 2

1

この質問は実際にはテンプレートに関するものではなく、インライン化に関するものだと思います。実行時のパフォーマンスのために、ほとんどの場合、コンパイラはおそらく正しい選択をします。関数が大きすぎてインライン化の恩恵を受けられないことがわかった場合、インライン関数のインライン化されていないバージョンを個別に生成する可能性があります。関数がテンプレートであるかどうか。各翻訳単位は関数の独自のバージョンを作成し、リンカーは使用するものを選択します (そして、うまくいけば、他の未使用のコピーを破棄しますが、実際にこれを行うかどうかは、リンカーとオブジェクト ファイル形式によって異なります)。

テンプレートとの相互作用は、テンプレート コードとそれが呼び出す関数 (テンプレート自体である可能性がある) との間のさまざまな相互作用を見るときに発生します。コードをインライン化しないように強制すると、コンパイラは関数呼び出しのオーバーヘッドを回避する機会がありません。多くの場合、テンプレートで使用される抽象化は非常に単純な関数です。たとえば、「イテレータをインクリメントする」および「イテレータを逆参照する」など、基礎となるポインター操作にマッピングされます。関数呼び出しの作成は、関数呼び出しのオーバーヘッドと最適化の機会の損失により、かなり高価になる可能性があります。 . ただし、コンパイラは実際にこれを見て、多くの場合正しい選択を行うことができます。

そうは言っても、私は特定のテンプレートの明示的なインスタンス化を作成することの大ファンです。たとえば、ヘッダーから IOStreams ライブラリの特定の部分を削除し、ライブラリで明示的にインスタンス化すると、特に最適化がオンになっている場合、コンパイル時間に大きな影響があります。整数に対して単純な出力関数を呼び出すと、多くのテンプレートがインスタンス化されます。 . このコードを独自のファイルに入れ、適切な最適化オプションでコンパイルしても、おそらくパフォーマンスに関して大きな違いはありませんが、コンパイル時間には大きな影響があります。ただし、これはパフォーマンスに間接的な影響を与える可能性があります。ライブラリを使用してコードのパフォーマンスをテストする反復回数を増やすことができます。

于 2012-10-06T15:18:34.667 に答える
0

inlineC++がそれを作るという保証がないので関数を明示的に宣言したとしてもinline、テンプレートをヘッダーにすべて実装するとinline実装が強制され、いくつかの問題が発生するとどう思いますか?

ほとんどの場合、2 番目のケースは必要ありませんが、そのようにすることはできますが、inline問題を回避するためには必要ありません。

于 2012-10-06T15:16:04.600 に答える