我正在阅读有关OpenMP和共享内存编程的内容,并忽略了这个具有整数x和两个线程的伪代码
thread 1
x++;
thread 2
x--;
这将导致竞争条件,但可以避免。我想使用OpenMP来避免它,应该怎么做?
我认为这是可以避免的:
int x;
#pragma omp parallel shared(X) num_threads(2)
int tid = omp_get_thread_num();
if(tid == 1)
x++;
else
x--;
我知道通过消除竞争条件会导致正确执行而且性能不佳,但我不知道为什么?
答案 0 :(得分:1)
如果多个线程正在修改x
,则代码会因竞争条件而面临风险。以您的示例的简化版本
int main()
{
int x = 0;
#pragma omp parallel sections
{
#pragma omp section {
++x;
}
#pragma omp section {
--x;
}
}
return x;
}
修改x
的两个线程可以互相交错,这意味着结果不一定是零。
保护修改的一种方法是将读取 - 修改 - 写入代码包装在critical
区域中。
另一个适用于此处简单操作的方法是使用++
标记--
和#pragma omp atomic
行 - 它们将使用存在的平台原生原子指令,这是与关键区域相比轻量化。
通常的另一种方法(但OpenMP并未严格保证)是将x
使用的类型更改为标准原子类型。只需将其从int
更改为std::atomic<int>
即可为您提供不可分割的++
和--
运算符,您可以在此处使用。