2012-06-05 15 views
13

短い紹介:私はマルチスレッドのコードを作成しており、2つのスレッド間で動的に割り当てられたオブジェクトを共有する必要があります。私のコードをクリーナーにするためには、各スレッドのオブジェクトを明示的に「削除」したいので、それでshared_ptrを使いたいのです。shared_ptrを使用したオーバーヘッドと実装

最初の質問:

私はshared_ptr-> operatorの実装は、実行時にいくつかの余分なオーバーヘッド(unique_ptrその後、例えば、より大きな)を持っているかどうかを知りたいです。私が話しているオブジェクトは、通常、オブジェクトのメソッドとフィールドにしかアクセスできないため、作成後に一度しかコピーされないlonglifeインスタンスです(スレッド間でそれらを分散すると)。

ご存知のように、shared_ptrは参照カウントのみを保護します。

2番目の質問:

のlibstdC++にshared_ptrを最適化されてどれだけ?それは常にmutexを使用するのか、原子操作を利用するのですか(私はx86とARMプラットフォームに焦点を当てます)?

+3

'shared_ptr'をうまく実装するには、' - > 'でポインタを逆参照するときにオーバーヘッドがゼロになるはずです。私はlibstdC++に慣れていないので、私はあなたの2番目の質問に答えることができません。あなたはヘッダーを持っているので、それがどのように実装されているかを見て簡単に調べることができます。 –

+2

コードがマルチスレッド化されている場合、GCCの共有ポインタは、参照カウンタに 'std :: atomic 'かそのようなものを使用します。それが本当のハードウェア(ロックフリー)かどうかは、コンパイラのバージョンに依存します - これはGCC 4.7.0で改善されたと思います。 –

+3

範囲外のコピー/割り当て/外出には、リフレッシュカウントのスレッドセーフな増分のために余分なオーバーヘッドがあります。 'operator->'は良い古い 'auto_ptr'のものとまったく同じに見えます。すなわち、オーバーヘッドがゼロになると期待できます。 – Damon

答えて

14

最初の質問:私はフィールドがスタック上にあるように、右shared_ptr<T>クラスのT*のローカルキャッシュを持って見ているoperator->

すべての実装を使用するには、operator->は、このように匹敵していますスタックを使用するコストはローカルT*です。オーバーヘッドはまったくありません。

2番目の質問:ミューテックス/アトミック

私はのlibstdC++はどうか標準的な設備または特定のグラムを通じて、x86プラットフォーム上でアトミックを使用することを期待++(古いバージョンでは)組み込み関数。私はBoostの実装がすでにそうしていると信じています。

ただし、ARMについてはコメントできません。

注:C++ 11では移動のセマンティクスが導入されているため、多くのコピーはshared_ptrの使用では当然避けられます。

注意:一般的にコピー/破壊のほとんどを避けるためにshared_ptrconstかどうか)への参照を使用することができますので、これらのパフォーマンスはあまり重要ではありません、shared_ptrhereの正しい使用方法について読みます。

+0

の場合は、 'make_shared'を使用していると言われています。このテンプレートをコンストラクタの初期化リストにどのように使用するのだろうか?例えば、クラス 'Foo'はフィールド' shared_ptr num'を持っているので、コンストラクタは次のようになります: 'Foo :: Foo(void):num(move(make_shared(new int(30)))){...}' ? – Goofy

+2

@Goofy:いいえ、 'make_shared'では' new'を明示的に実行せず、一方、作成したオブジェクトの型を明示的に渡す必要があります。一時的に 'move'への呼び出しも不要です。したがって、次のようになります: 'Foo :: Foo():num(std :: make_shared ()){}' –

+0

大丈夫、私はまだC++の値に慣れています;) – Goofy

12

GCCのshared_ptrは、シングルスレッドコードではロックもアトミックも使用しません。マルチスレッドコードでは、アトム比較スワップ命令がCPUによってサポートされている場合はアトミック操作を使用し、そうでない場合は参照カウントがミューテックスによって保護されます。 i486以降ではアトミックを使用し、i386はcmpxchgをサポートしていないため、ミューテックスベースの実装を使用します。私はARMがARMv7アーキテクチャー用にアトミックを使用していると考えています。

std::shared_ptrstd::tr1::shared_ptrの両方に同じ。)

+1

GCCはコードはマルチスレッドであるかどうか? –

+0

@DrewNoakes - あなたは#defineでそれを伝える必要があります。 –

+0

これは参考になりますか?私は少しの検索をして、1つを見つけることができません。 –