避免OpenMP中的竞争条件?

时间:2017-08-17 14:04:01

标签: openmp shared-memory race-condition critical-section

我正在阅读有关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--;

我知道通过消除竞争条件会导致正确执行而且性能不佳,但我不知道为什么?

1 个答案:

答案 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>即可为您提供不可分割的++--运算符,您可以在此处使用。