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

Is necessary a #pragma omp atomic for a concurrent flag set?

在使用 OpenMP 的 C 程序中,我想在任何线程(我不需要知道是哪个线程)满足条件时设置一个标志。 如果标志变量由所有线程共享,并且标志被初始化为 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”指令吗?

即使存储的值小于字长,也需要避免两个线程读写相同内存位置的竞争条件。您将需要 #pragma omp atomic write#pragma omp atomic read 对来避免竞争条件。因为不能用 atomic 构造保护 if(flag) {...},所以必须引入一个临时变量来将标志读入:

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

此外,您可能需要通过使用 flush 构造或添加 seq_cst(顺序内存一致性)或一对 [= atomic 结构的 17=] 和 release 子句。

鉴于您只需要 并行区域之后的共享结果,您可以使用 reduction 而不是 atomic

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

两种解决方案都非常好。仅当您经常设置 flag 时,减少才具有性能优势。