そのため、SO やインターネット全般では、OpenMP の使いやすい#pragma
ディレクティブを C++ の同様に使いやすい STL コンテナーと連携させる方法について、多くの混乱とフラストレーションがあります。
誰もが STL の回避策について話しますが、、 、 などvector
の非ランダム アクセス / 双方向コンテナーについてはどうでしょうか。map
list
set
私はこの問題に遭遇し、非常に単純で明白な回避策を考案しました。STL についてここに示しますmap
が、明らかに一般化できます。
シリアル版:
for (std::map<A,B>::iterator it = my_map.begin();
it != my_map.end();
++it)
{ /* do work with it */ }
STL で OpenMP を使用するための私の提案したソリューションmap
:
//make an array of iterators.
int loop_length = my_map.size();
std::map<A,B>::iterator loop_array[ loop_length ];
std::map<A,B>::iterator allocate_it = my_map.begin();
for (int j=0; j<loop_length; ++j)
loop_array[j] = allocate_it++;
// now you can use OpenMP as usual:
#pragma omp parallel for
for (uint j=0; j<loop_length; ++j)
{ /* do work with loop_array[j] */ }
ただし、私は OpenMP の専門家とはほど遠いので、提案された回避策が効率的で優れた方法であるかどうかを知りたいと思います。
for ループ内での STL コンテナーのスレッドセーフな処理は、プログラマーの責任であると想定してください。
最後に、私の提案したソリューションは、次の一般的に提案されたソリューションよりも効率的ですか(この SO の質問への回答を参照してください)。
#pragma omp parallel
{
for (std::map<A,B>::iterator it = my_map.begin();
it != my_map.end();
++it)
#pragma single nowait
{ /* do work */ }
}