2016-12-16 5 views
3

k要素のベクトルを作成する必要があります。すべてのスレッドはその部分を作成し、k * 25%とし、任意のインデックスでベクトルに配置する必要があります。このexampleから駆動、私はこのような何かしようとしていました:ベクトルを並行して配置する場合、重要でない順序

std::atomic<std::vector<aClass<templatedType>>> H; 

をが、これは動作しません:それは自明コピー可能ではありませんので、

/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/atomic:823:13: error: 
     _Atomic cannot be applied to type 
     'std::__1::vector<StableHashFunction<int>, 
     std::__1::allocator<StableHashFunction<int> > >' which is not trivially 
     copyable 
    mutable _Atomic(_Tp) __a_; 

- と回避策は甘くはありません。さらに、私はそれが原子的である必要がありますか?

それは私が順序を気にしないとき、私はまだ原子を使うべきですか?言い換えれば、データ競合は要素の順序にのみ影響を及ぼしますか、要素を覆うような副作用を引き起こす可能性があります(k要素の代わりに、最後にk-1しか持たない)?

+0

'一back()'や 'emplace_back()'、アトミック操作ではありませんので、あなたは 'のstd :: mutex'のようないくつかの同期メカニズムとそれらを保護する必要があります。 –

+0

サイズKのベクトルを作成してから、ベクトルの各スレッド更新部分を作成して、スレッド間でデータを共有しないようにします。 – Jarod42

+0

@ Jarod42それは私の最初の考えでしたが、それを行うには、ベクトルのすべての要素をデフォルトで構築する必要があります。 – NathanOliver

答えて

4

あなたが並列にアイテムを挿入しようとすると、問題が唯一のベクトルは、そのサイズを変更しなければならない場合に発生:同時挿入がメモリ内の同じ場所を更新しなければならない、不正な動作原因

(クラッシュは、アイテムなどを失いました)

しかし、既存のベクトルの異なる要素を同時に設定しても問題は発生しないため、この問題の一般的な解決方法はベクトルを事前に割り当てることです。

このアプローチでは、ベクトル要素のデフォルトのコンストラクタと、各スレッドがベクトルに配置するアイテムの正確な数に関する事前知識が必要です。たとえば、スレッド0が100個の要素を配置することが分かっている場合、スレッド1は120個の要素を配置し、スレッド2は110個の要素を配置し、100 + 120 + 110要素のベクトルを事前に割り当てます。各スレッドに独自の初期インデックス:0,100、および220を与えます。これで、各スレッドは並行性の問題に陥ることなく、アイテムをベクトルに配置できます。

Vector subdivision

+0

私はラインキャッシュについて興味があります。インデックス99と100の要素が同じキャッシュライン上にあるとどうなりますか? – Amadeus

+0

@Amadeusこれは偽の共有と呼ばれ、有効な懸案事項です。スレッドが開始時に開始し、スレッドが終了すると、おそらくそれは見えません。 – NathanOliver

+0

@Amadeusこれは多くの問題を引き起こすべきではありません。最初に書き込まれるコアは、他のコアのキャッシュラインを無効にするので、次にデータが要求されたときにメモリから読み取らなければなりません。最初のスレッドが99番地に書き込もうとするまでに、2番目のスレッドは100番地で長時間処理しなければならず、すべての作業を上書きする必要があるため、小さなスローダウンが問題ではありません場所199かそこらへ。 – dasblinkenlight

1

アトミックをベクトルまたは別のクラスで使用する場合は、代わりにポインタを使用できます。あなたのケースでは、ベクトルへのスレッドセーフなアクセスを行うためにmutexを使用するか、TBB libraryを使用する必要があります。このライブラリはあなたにとって必要な機能をすべて備えています。

+0

私はライブラリを使いたくはありませんが、ヒントのおかげで、将来興味のあるユーザーに+1してください。 – gsamaras

関連する問題