并发标志集是否需要#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
时,减少才具有性能优势。
在使用 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
时,减少才具有性能优势。