2016-10-09 3 views
2

std::unordered_map<int,T>に約100の記入項目を記入する必要があります。これらは、構築するために高価であり、私はそれを同時に行うためのOpenMPを使用したい:std :: unorderd_mapを同時に入力するにはどうすればよいですか?

unordered_map<int, T> mapWithTs; 

#pragma omp parallel for schedule(dynamic) // dynamic because T constructs in some unpredictable time. 
for(int i=0; i<100; ++i) 
{ 
    mapWithTs.emplace(i, {i}) // calls the constructor T(i) 
} 

私はマップが焼き直しになり、その後、イテレータが有効でなくなることをお読みください。私はこの仕事をするために何をしなければなりませんか?

さらに、標準ライブラリの並行処理ソリューションはどのように見えますか?

+3

建設費がかかりますが、安価に移動できますか?それぞれのスレッドが独自のベクトルを作成して1つのスレッドがそのベクトルオブジェクトをマップに移動できますか? – Galik

+2

複数のスレッドを作成し、それぞれが独自のマップを作成した後、(単一のスレッドで)マップをマージします。 –

+0

地図へのアクセスを同期(相互排除)するだけで済みます。私はOpenMPとの同期をどうやって行うのかはわかりませんが、おそらくあなたはそうしています。そうでない場合は、ドキュメントを参照してください。 –

答えて

2

このような高価なインスタンスを作成する場合は、shared_ptr、生ポインタ&cを参考にして助けてください。「マップ」とも呼ばれるステップで独自のスタックローカルマップを作成することをお勧めします。正規表現で「reduce」と呼ばれるステップで、それらをすべて1つのスレッドで結合します。

これは「マップ削減」アルゴリズムと呼ばれます。

は、「マップ」コレクション

のすべての要素に関数を適用する関数の通常の名前は「削減」されることにより、1つの値を、コレクション内のすべての要素を兼ね備えた機能の通常の名前です。 Galikとヨーマンで述べたようにその名を現在の中間結果で関数を呼び出すと、各要素

:)

+0

注意すべき点の1つは、 'new'、' malloc'などのヒープメモリを暗黙的に使用する「マップ」操作を使用することです。ほとんどの実装では、すべてのスレッドに対して単一のヒープが提供されるため、ヒープメモリを使用すると、ロック付きの共有マップを明示的に使用するのと同様の競合およびロックが発生する可能性があります。 –

+0

それが低いときに意味するか?あるいは、JVM、GNU libC++、BSD libC++のヒープは並行割り当てになると非常に非効率的ですか? – yeoman

+0

*低すぎるとはどういう意味ですか?あるいは、JVM、GNU libC++、BSD libC++のヒープは、並行割り当てに関しては驚くほどひどく非効率的ですか?いずれか。これは、ヒープ実装とメモリ使用パターンに依存します。私の経験では、マルチスレッド対応のヒープはほとんどの場合非常にうまく動作する傾向があります。しかし、私はそのようなヒープ実装を減らしてアプリケーションを効果的にシングルスレッド化する使用パターンを見てきました。 6つのスピードアップが8つのスレッドを実行することを期待してベンチマークを行い、スピードアップがまったくないことを知っていれば、それは気付くだけのことです。 –

0

、あなたのオブジェクトの安い操作を移動させることが不可欠です。それはすでに(建設は重いが、移動は安い)、あなたは大丈夫です。それ以外の場合は、オブジェクトをuniq_ptrに置く必要があります。このrehash後も安い操作(はい、rehashは線形時間がかかりますが、0(1)償却複雑さ)です。だからあなたは再ハッシュについて心配する必要はありません。

次は地図の塗りつぶしです。複数のスレッドから作業しているので、複数のスレッドが同時に動作しないようにする必要があります。 #pragma omp criticalやstd :: mutexのようなものが必要です。そしてここで重要な部分があります:あなたが今のようにemplaceを使用すると、重いTコンストラクタは、並列化の全体的な考えを殺すクリティカルセクションで実行されます。したがって、この特定のケースでは、事前にオブジェクトTを作成してから、クリティカルセクションに入り、オブジェクトをハッシュマップに移動することをお勧めします。

Tの構築が実際には重い操作(それにはかなり時間がかかり、unordered_mapに値を挿入する)があれば、それはすべてです。スレッドごとのリストを作成してマップに挿入することで、パフォーマンスが向上することはありません。それ以外の場合、yeomanの答えは、コードの複雑さの増加による追加のメリットをもたらす可能性があります。

関連する問題