考虑以下串行函数。当我并行化我的代码时,每个线程将从并行区域内调用此函数(未显示)。我试图使这个函数既线程安全又高效(快速)。
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”(不管它是什么)的存储值。偶尔,在调用“new A”时,将需要计算并存储一个值。
那么我应该在哪里放置#pragma omp critical?
虽然容易,但在这一切周围放置#pragma omp critical非常低效,因为每个线程将经常执行这个操作,并且通常是只读情况。
有没有办法实现“单向”critical或“单向”锁定例程?也就是说,涉及迭代器的上述操作仅在“else”语句中写入my_map时才“锁定”。但是多个线程应该能够同时执行.find调用。
希望我表达清楚。谢谢。
.insert
,这也是真的吗?(即,在此线程处于.find
调用内部时)。 - cmooperator[]
,如myMap[i] = 3.14*i*i
将导致多次写入。然而,myMap.insert(std::pair<int, float>(i, 3.14*i*i))
实际上只会写入一次。 - cmo