次のシリアル関数を検討してください。私のコードを並列化すると、すべてのスレッドは並列領域内からこの関数を呼び出します(図示せず)。私はこのスレッドセーフと効率的(高速)にしようとしています。C++ OpenMP critical:「一方向」ロック?
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
ルーチンを実装する方法はありますか?つまり、イテレータを含む上記の操作は、else
ステートメントのmy_map
に書き込むときにのみ "ロック"されるべきです。しかし、複数のスレッドが.find
コールを同時に実行できる必要があります。
私は意味があると思います。 ありがとうございます。
:)しかし私のものよりも優れている。しかしcritical' 'の使用は、私が心配していた非効率である - 複数のスレッドがsimlutaneouslyによる' critical'にマップを読み取ることができません。 – cmo
しかし 'atomic'は良いアイデアです。では、書き込み領域の周りに「アトミック」と「フラッシュ」を配置するだけでいいですか? - 読み込み領域は指示する必要がありますか? – cmo
@CycoMatto私は知っています。私は「原子」と「フラッシュ」で賢明な何かをして、私の間違いを認識し、私の答えを編集したと思った。それはあなたの問題につまずく誰かに有用かもしれない情報を提供しますが、あなたが望むロックされた場合の書き込み動作を提供していません。 –