c ++ OpenMP critical:“one-way”锁定? [英] c++ OpenMP critical: "one-way" locking?
问题描述
请考虑以下串行函数。当我并行化我的代码,每个线程将从并行区域(未示出)内调用此函数。
Consider the following serial function. When I parallelize my code, every thread will call this function from within the parallel region (not shown). I am trying to make this threadsafe and efficient (fast).
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时,都必须计算并存储一个值。
Almost every single time this function is called, the threads will successfully "find" the stored value for their "A" (whatever it is). Every once in a while, when a "new A" is called, a value will have to be calculated and stored.
所以我应该把 #pragma omp critical
?
虽然很简单,但是效率非常低。 c> #pragma omp critical 所有这一切,因为每个线程将不断地这样做,它通常是只读的情况。
Though easy, it is very inefficient to put a #pragma omp critical
around all of this, since each thread will be doing this constantly and it will often be the read-only case.
是否有任何方式实现单向临界
或单向锁
常规?也就是说,当在 else
语句中的 my_map
中写入时,上述涉及迭代器的操作应该是但是多个线程应该能够同时执行 .find
调用。
Is there any way to implement a "one-way" critical
, or a "one-way" lock
routine? That is, the above operations involving the iterator should only be "locked" when writing to my_map
in the else
statement. But multiple threads should be able to execute the .find
call simultaneously.
我希望我有意义。
谢谢。
I hope I make sense. Thank you.
推荐答案
根据这个链接在堆栈溢出插入 std :: map
无效迭代器。对于 end()
迭代器也是如此。 这是一个支持链接
According to this link on Stack Overflow inserting into an std::map
doesn't invalidate iterators. The same goes for the end()
iterator. Here's a supporting link.
不幸的是,如果您不使用关键部分,插入可能会发生多次。此外,由于您的 calculate_value
例程可能在计算上是昂贵的,您必须锁定,以避免这 else
两次使用相同值 A
,然后插入两次。
Unfortunately, insertion can happen multiple times if you don't use a critical section. Also, since your calculate_value
routine might be computationally expensive, you will have to lock to avoid this else
clause being operated on twice with the same value of A
and then inserted twice.
以下是一个示例函数,多重插入:
Here's a sample function where you can replicate this incorrect multiple insertion:
void testFunc(std::map<int,float> &theMap, int i)
{
std::map<int,float>::iterator ite = theMap.find(i);
if(ite == theMap.end())
{
theMap[i] = 3.14 * i * i;
}
}
然后这样调用:
std::map<int,float> myMap;
int i;
#pragma omp parallel for
for(i=1;i<=100000;++i)
{
testFunc(myMap,i % 100);
}
if(myMap.size() != 100)
{
std::cout << "Problem!" << std::endl;
}
编辑:编辑以纠正earler版本中的错误。
edited to correct error in earler version.
这篇关于c ++ OpenMP critical:“one-way”锁定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!