gpt4 book ai didi

C++ OpenMP 关键 : "one-way" locking?

转载 作者:太空狗 更新时间:2023-10-29 21:05:15 25 4
gpt4 key购买 nike

考虑以下串行函数。当我并行化我的代码时,每个线程都会从并行区域(未显示)内调用此函数。我正在努力使这个线程安全高效(快速)。

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 调用。

希望我说的有道理。谢谢。

最佳答案

根据 this link on Stack Overflow插入 std::map不会使迭代器无效。 end() 也是如此迭代器。 Here's a supporting link.

不幸的是,如果不使用关键部分,插入可能会发生多次。另外,由于您的 calculate_value routine 可能在计算上很昂贵,你将不得不锁定以避免这种情况 else以相同的值 A 对子句进行两次操作然后插入两次。

这是一个示例函数,您可以在其中复制这个不正确的多重插入:

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;
}

编辑:编辑以更正早期版本中的错误。

关于C++ OpenMP 关键 : "one-way" locking?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10522026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com