我有大量的整数集,我依次将它们放入指针向量中。我需要能够并行更新这些整数集而不会导致竞争条件。进一步来说。我正在使用OpenMP的“并行”构造。
为了处理共享资源,OpenMP提供了一个方便的“原子指令”,它允许人们在不使用锁的情况下避免特定内存块上的竞争条件。 如果我可以使用“原子指令”来防止同时更新我的整数集会很方便,但是,我不确定这是否可行。
基本上,我想知道以下代码是否会导致竞争条件
vector< set<int>* > membershipDirectory(numSets, new set<int>);
#pragma omp for schedule(guided,expandChunksize)
for(int i=0; i<100; i++)
{
set<int>* sp = membershipDirectory[rand()];
#pragma omp atomic
sp->insert(45);
}
请注意,我对索引使用随机整数,因为在我的应用程序中,任何线程都可以访问任何索引(我的大型应用程序中有一个随机元素,但我不需要详细介绍)。
我见过一个similar example of this for incrementing an integer,但我不确定它在使用指向容器的指针时是否有效。
答案 0 :(得分:2)
在搜索之后,我在openmp.org上找到了OpenMP C and C++ API manual,在2.6.4节中,描述了原子结构的局限性。
基本上,原子指令只能与以下运算符一起使用:
一元: ++, - (前缀和后缀)
二进制: +, - ,*,/,^,&安培;,|,&LT;&LT;,&GT;&GT;
所以我只会使用锁!
(在某些情况下,关键部分可能更可取,但在我的情况下,锁将提供对共享资源的细粒度访问,从而产生比关键部分更好的性能。)
答案 1 :(得分:1)
你不应该使用atomic表达式是函数调用,它只适用于简单表达式(可能内置函数:幂,平方根)。
而是使用关键部分(命名或默认)
答案 2 :(得分:0)
您的代码不清楚。假设membershipDirectory [5]实际上是membershipDirectory [i],则不需要原子指令。例如,对于两个处理器,OpenMP产生两个线程,一个处理i = 0-49,另一个处理50-99个间隔。在这种情况下,不需要保护membershipirectirect目录[i]。需要使用原子指令来保护一些不依赖于循环索引的公共资源,例如总和。