2015-09-21 37 views
11

私は実行する必要がある機能を持っていますn=1000回。この関数はモンテカルロスタイルのシミュレーションを行い、結果としてintを返します。 nthreads=4を並行して実行したいと思います。スレッドが1サイクル終了すると、結果はstd::vector<int>になるはずです。 したがって、1000サイクル後、私は1000 intのベクトルを得ました。これは統計で調べることができます。スレッドセーフstd :: atomic <vector<int>>を作成できますか?

std::vectorはスレッドセーフではないため、私はstd::mutex(これは確かにうまくいくでしょう)と考えました。

しかし、私はベクトルをアトミックに宣言してミューテックスを回避することができますか? std::atomic<std::vector<int>>はありますか?それにpush_backなどを使用できますか?

+0

std :: atomic >がコンパイルされましたか? – DawidPi

+0

私はこの機械で試すことはできません...しかし、ちょうど原子を介して来た。 – dani

+0

私はちょうどあなたが1000の実行を持っていることをあなたが最初から知っていて、あなたのコンテナが正確に1000の結果を保存し、なぜ動的コンテナを使用したいのかを追加したいのですか?私は、std :: vectorはその実装で配列を使用していることを知っています。したがって、最初から十分なスペースを確保しておくと、再配置は必要ありません(std :: arrayを使用してもパフォーマンスは向上しません)。 – dptd

答えて

8

あなたはそうする必要はありません。あなたは異なるオブジェクト

に書き込む

  • オブジェクトを読み取る

    • 場合には、複数のスレッドからJA std::vectorにアクセスするには、完全に大丈夫ですだからあなたはサイズのベクトルを作成し、確認してくださいn=1000スレッド番号(1〜4)に応じて、0〜249,250〜499などの要素をスレッドに割り当てます。

      したがって、それぞれのスレッドはn/nthreads要素を計算します。

  • +9

    ベクトルの一部をスレッドに割り当てる前に、ベクトルのサイズを適切に調整することが非常に重要です。サイズ変更はスレッドセーフではありません。 – Jeremy

    +1

    しかし、このようにしても、リーダーとライターを同期させる必要があります。特に 'atomic_int'や' std :: atomic 'を使わない限り、' int'へのアクセスがすべてのアーキテクチャ上で原子的であることが保証されていないためです。 – blubberdiblub

    4

    原子は、簡単にコピー可能なタイプでインスタンス化できます。 Vectorはそのような型ではありません。

    +0

    質問は答えではありません。質問にコメントとしてOPに質問を書いてください。 – Gombat

    +0

    'int k [1000]'のようなCスタイルの配列は "トリビュアコピー可能な型"ですか? – dani

    +0

    'k'は単なるポインタです。ポインタは簡単にコピー可能です。しかし、これをテーブルとして使うのは、 'k 'が普通のポインタであるのでスレッドセーフであるのかどうかは分かりませんが、' k(5) 'は' *(k + 5) 'と' k +別のポインタが、私はそれを本当に確信していません。 'std'から' is_trivially_copyable'をチェックすることができます。通常は、スレッドセーフコンテナのために独自の 'threadsafe_vector'型を作成します。 – DawidPi

    13

    C++ 11§29.5/ 1は、原子ジェネリッククラステンプレートがあり

    言います。テンプレート引数Tの型は単純にコピー可能(3.9)でなければならない。

    trivially copyableとは何ですか?

    §3.9を一括コピー可能タイプ自明と呼ばれる

    スカラー型、自明にコピー可能クラスタイプ(条項9)、そのようなタイプのアレイ、およびこれらの型(3.9.3)のCV修飾バージョンを伝えます。

    • ない非自明なコピーコンストラクタ
    • を有していないがない以外を持っていない。

      自明にコピー可能クラスは、そのクラスである:(std::vectorがあるの)クラスタイプについて

      代数移動コンストラクタ

    • には重大なコピー代入演算子はありません
    • は自明コピーできませんので、あなたがstd::atomic<std::vector<int>>を使用することはできません何の非自明な移動代入演算子
    • このリストstd::vectorによると、些細なデストラクタ

    を持っていない持っています。

    あなたは(push_back)のような別の場所に再割り当てするベクトルを必要とするメソッドを使用する必要はありませんので、事前にサイズを知っているし、ので。あなたが必要なintを事前に割り当てるとpreconstructするstd::vector<int>::resizeまたはサイズのコンストラクタを使用することができます秒。そのため、あなたの同時実行スレッドは、ベクター自体ではなく要素を操作する必要はありません。

    を同じ要素に別のスレッドからのアクセスがない場合は何の競合状態がありません。

    同じのために行きますint k[1000]これは簡単にコピー可能ですが、あなたはそれが必要なわけではありませんスレッドは配列/ベクトル/リスト自体を変更するのではなく、要素を変更します。

    関連する問題