11

そのため、SO やインターネット全般では、OpenMP の使いやすい#pragmaディレクティブを C++ の同様に使いやすい STL コンテナーと連携させる方法について、多くの混乱とフラストレーションがあります。

誰もが STL の回避策について話しますが、、 、 などvectorの非ランダム アクセス / 双方向コンテナーについてはどうでしょうか。maplistset

私はこの問題に遭遇し、非常に単純で明白な回避策を考案しました。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  */   }

}
4

1 に答える 1

5

OpenMP* はtaskバージョン 3.0 以降、STL で使用するのに非常に便利な構文を提供します。

for (std::map<A,B>::iterator it = my_map.begin();
        it != my_map.end();
        ++it)       
{
   #pragma omp task
   { /* do work with  it   */  }
}

もちろん、これが機能するためには、反復間のデータ依存関係が存在してはなりません。

于 2012-05-04T22:01:56.253 に答える