并发标志集是否需要#pragma omp原子?

时间:2019-04-27 13:07:42

标签: c multithreading openmp

在使用OpenMP的C程序中,我想在任何线程(不需要知道哪个线程)满足条件时设置一个标志。 如果flag变量由所有线程共享,并且将该标志初始化为0(在多线程部分之前),并且任何线程都会将该值设置为1或0(它们都始终设置为相同的值),我是否需要“ #pragma omp atomic”指令?

例如,以下代码段:

//DataStruct is self defined data structure
function (DataStruct *data) {
  int i,flag=0;

  #pragma omp parallel for
  for(i=0;i<data->maxval;i++) {
    //Do stuff
    if (/*check condition*/) {
      //data->printMesage is 0 or 1, and doesn't change. It is fixed
      //before calling this function
      //data->printMesage is also an int variable
      flag=data->printMesage;
    }
  }
  //End of for loop. The code is running in
  //single thread from here
  if (flag) {
    //Print message
  }
}

有必要在“ flag = data-> printMesage;”之前添加“ #pragma omp atomic”指令?

2 个答案:

答案 0 :(得分:2)

即使存储的值小于字大小,也需要避免两个线程在相同的内存位置进行读写的竞争状态。您将需要一对#pragma omp atomic write#pragma omp atomic read来避免竞争情况。因为您无法使用if(flag) {...}构造来保护atomic,所以必须引入temp变量以将标志读入:

#pragma omp atomic read
tmp = flag
if (tmp) { ... }

此外,您可能需要通过使用flush构造或添加seq_cst(顺序内存一致性)或一对{{1}来使线程的内存视图一致。 }和acquire子句添加到release结构中。

答案 1 :(得分:2)

鉴于您只需要在并行区域之后的 共享结果,则可以使用reduction代替atomic

#pragma omp parallel for reduction(max:flag)
for(i=0; i<data->maxval; i++) {

这两个解决方案都很好。仅当您可能非常频繁地设置flag时,降低的性能才会带来好处。