次のシリアル関数を考えてみましょう。コードを並列化すると、すべてのスレッドが並列領域内からこの関数を呼び出します (表示されていません)。私はこれをスレッドセーフで効率的 (高速) にしようとしています。
float get_stored_value__or__calculate_if_does_not_yet_exist( int A )
{
static std::map<int, float> my_map;
std::map::iterator it_find = my_map.find(A); //many threads do this often.
bool found_A = it_find != my_map.end();
if (found_A)
{
return it_find->second;
}
else
{
float result_for_A = calculate_value(A); //should only be done once, really.
my_map[A] = result_for_A;
return result_for_A;
}
}
ほとんどの場合、この関数が呼び出されるたびに、スレッドは格納されている "A" の値 (それが何であれ) を正常に "検索" します。時々、「新しい A」が呼び出されると、値を計算して保存する必要があります。
では、どこに置くべき#pragma omp critical
ですか?
簡単ですが、各スレッドがこれを常に実行し、多くの場合読み取り専用になるため、これらすべてを回避するのは非常に非効率的です。#pragma omp critical
critical
「一方向」または「一方向」lock
ルーチンを実装する方法はありますか? つまり、反復子を含む上記の操作はmy_map
、else
ステートメントへの書き込み時にのみ「ロック」する必要があります。.find
ただし、複数のスレッドが呼び出しを同時に実行できる必要があります。
私が理にかなっていることを願っています。ありがとうございました。