在使用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”指令?
答案 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
时,降低的性能才会带来好处。