2012-05-04 8 views
5

大きなベクトルを設定する関数の戻り値としてauto_ptrを使用すると、関数がソース関数になります(内部auto_ptrが作成され、 const auto_ptr)。しかし、データにアクセスするためには、auto_ptrを削除する必要があるため、この関数をSTLアルゴリズムで使用することはできません。私が推測する良い例は、サイズNのベクトルのフィールドであり、各ベクトルは100の成分を有する。 Wetherは、100の成分ベクトルを値ごとに返します。あるいは、Nが大きい場合、refは同じではありません。また大きな値のベクトルに対する戻り値の最適化とauto_ptr

、私はこの非常に基本的なコードを試してみてください。

class t 
{ 
    public: 
     t() { std::cout << "ctor" << std::endl; } 
     ~t() { std::cout << "dtor" << std::endl; } 
}; 

t valueFun() 
{ 
    return t(); 
} 

std::auto_ptr<t> autoFun() 
{ 
    return std::auto_ptr(new t()); 
} 

autoFunと楽しコールの両方をので、私は実際に自動変数これを見ることができない出力

CTOR デストラクタ

となりますreturn文に渡されるように作成されています。これは、戻り値の最適化がvalueFun呼び出しに設定されていることを意味しますか?この場合、valueFunは2つの自動オブジェクトを作成しますか?

このような大きなデータ構造の母集団を関数で最適化するにはどうすればよいですか?

+0

RVOがあなたの大きなベクトルでも機能するかどうか尋ねていますか?もしそうなら、上記のような例でテストすることはできませんか? – juanchopanza

+0

私がテストすると、すべてのコンパイラ/プラットフォームで動作するのでしょうか?コンパイラの仕様を読めば、RVOがまったく含まれていることをどのように知ることができますか?別のコンパイラを使用してHPCクラスター上でコードをコンパイルし、そのライブラリーが大きい場合はどうなりますか? – tmaric

+0

ええ、あなたのことが分かります。コンパイラが許可されているが、必須ではないことの1つであるため、決して確実ではありません。あなたはC++ 11をサポートしていますか? – juanchopanza

答えて

4

この時点で最も近代的なコンパイラのサポートムーブセマンティクス(または右辺値参照を技術的に)このオプションと動的割り当ては最適ではない可能性があります。


このディスカッションを掘り下げる前に、これはボトルネックですか?

プロファイルが作成されておらず、ボトルネックであることが確認された場合、このディスカッションは完全にオフになる可能性があります。デバッグビルドのプロファイリングよりも覚えがないです。で今


、C++ 03そこにいくつかのオプションは、最もおいしいから少なくとも1つに、以下のとおりです。

  • 信頼コンパイラ:無名の変数もデバッグでRVOを使用するには、のために、GCCでビルドします例。
  • コンパイラの出力個人的に

をチェック

  • ヒープに割り当て、(スマートまたはない)ポインタを返す「アウト」パラメータ(参照渡し)
  • を使用し、私は私のコンパイラを信頼しますプロファイラーが私が間違っていることを証明しない限り、

    returnステートメントがあるたびにRVOが起動できない場合、移動コンストラクタ(使用可能な場合)が自動的に使用できるため、C++ 11では移動セマンティクスがより自信を持って助けます。 vector上のコンストラクターは汚れて安いです。

    だから、次のようになります。

    • 信頼コンパイラ:RVOまたはセマンティクス
    • を移動するには、ヒープ上に割り当てるとunique_ptr

    を返しますが、実際に第二の点のみに使用する必要がありますどちらか移動セマンティクスがあまり役に立たない少数のクラス:移動セマンティクスのコストは、通常、sizeofの返り値に比例します。例えば、のサイズは10*sizeof(T)になります。ヒープ割り当ての恩恵を受ける可能性があります+ unique_ptr


    タンジェント:あなたはすでにあなたのコンパイラを信頼しています。危険について警告するためにそれを信頼し、危険な/おそらく不正確な構造について警告するためにそれを信頼し、コードを機械アセンブリに正しく翻訳することを信頼し、相当なスピードアップを得るために意味のある最適化を適用することを信頼します。明らかなケースでRVOを適用するコンパイラを信頼しないと、心臓外科医に$ 10の請求書を信用していないようなものです。 ;)

  • +1

    正直、ありがとう! :) – tmaric

    1

    コンパイラがvalueFunの戻り値最適化を行うことはかなり確信しています。したがってauto_ptrには必要ではない条件

    に基づいて異なるオブジェクトを返す

    • 戻りパラメータ
    • 、そして次のようになります戻り値の最適化は、コンパイラによって適用することができない主なケースがありますヒープを使用する必要があるためにさらに遅くなります。

      このような大きなベクトルを移動するコストが心配されている場合は、移動セマンティクス(C++ 11のstd::vector aCopy(std::move(otherVector)))を使用することができます。これらはRVOとほぼ同じくらい速く使用できますどこにでも(RVOが使用できないときには、戻り値に使用されることが保証されています。)

      私は信じている多くあります

    +0

    "かなり確かなこと"は私を少し気にさせるものです。 :)私の立場からすれば、もし100sのコアでこのことを実行するのであれば、それが時間とともに成長するならば、コードが何をするかを100%確かめる必要があります。 – tmaric

    関連する問題