避免在OpenMP中竞争(在并行for循环中)

时间:2010-10-17 05:36:45

标签: openmp race-condition

我正在用C编写一个OpenMP程序。我有这个共享数组“数据”,所有线程都在更新。我想确保每个线程都已完成读取部分,并在执行下一个语句data [j] = temp之前将值存储在temp中。

我尝试在两个语句之间放置#pragma omp barrier,但编译器会抛出错误。请帮忙。

#pragma omp parallel for shared(data)

for (j = 0; j < numints; j++){

     if (j >= max_j)

     {

              temp = data[j] + data[j - max_j];
             data[j] = temp; 
     }

}

2 个答案:

答案 0 :(得分:2)

正如您所见,barrier无效;对于这种特殊的操作,critical相当重。原子重量轻于关键;你总能做到

if (j >= max_j)
{
    #pragma omp atomic
    data[j] += data[j-max_j]; 
}

但是你应该总是警惕在循环中有任何这样的构造(原子,关键) - 它会杀死性能,因为它会杀死并行性(毕竟,它的全部目的)。

使用这段代码知道你要完成什么会有所帮助,因为即使一旦更新中的数据竞争被消除,(例如)数据[maxints-1]的最终结果将取决于什么订单数据[maxints-1-max_j],data [maxints-1-2 * max_j] ..已更新,OpenMPs并行明确无法保证。 (你可以使用有序的构造,但这几乎不比没有使用并行构造好。)

如果maxints < 2*max_j,那么这很容易;你可以做到

#pragma omp parallel for shared(data)
for (j = max_j; j < numints; j++){
    data[j] += data[j-max_j];
}

并且您根本不需要任何同步,因为每个线程只更新一个数据[j]而没有任何其他任何数据依赖。但我得到的印象是(a)它不是,而且(b)这是一段更大的代码片段......

答案 1 :(得分:1)

屏障用于同步。 您想使用关键部分:http://msdn.microsoft.com/en-us/library/b38674ky%28VS.80%29.aspx