C OpenMP关于循环

C OpenMP关于循环,c,for-loop,openmp,C,For Loop,Openmp,我有一个OpenMP代码片段,如下所示: #ifdef _OPENMP #pragma omp parallel for default(none) \ private(i, a_output) \ shared(n, t_input, t0, trace_amp) #endif for (i = 0; i < n; i++){ if( t_input >= t0[i] ) { a_output =

我有一个OpenMP代码片段,如下所示:

#ifdef _OPENMP
  #pragma omp parallel for default(none) \
  private(i, a_output) \
  shared(n, t_input, t0, trace_amp)
#endif
    for (i = 0; i < n; i++){
        if( t_input >= t0[i] )
        {

                a_output = trace_amp[i];

                return a_output;
        }
    }
\ifdef\u OPENMP
#默认值为pragma omp parallel(无)\
专用(i,a_输出)\
共享(n,t_输入,t0,跟踪放大器)
#恩迪夫
对于(i=0;i=t0[i])
{
a_输出=跟踪_amp[i];
返回一个输出;
}
}

这个代码正确吗?为什么
a_输出必须是私有的?可以分享吗

正如@1201programalam所说,在并行区域内不能有
return
语句。编译器甚至不编译代码

$ gcc Untitled-1.c -fopenmp
Untitled-1.c: In function ‘main’:
Untitled-1.c:7:20: error: invalid branch to/from OpenMP structured block
             return a_output;

$ clang Untitled-1.c -fopenmp=libomp
Untitled-1.c:7:13: error: cannot return from OpenMP region
            return a_output;
            ^
1 error generated.
然而,OpenMP规范的4.0版带来了一个新的指令:
cancel
。使用它,您可以中断并行区域的执行。它给总执行时间增加了一点开销,因为在每次迭代中,线程都会测试它们是否必须停止

您可以尝试通过以下方式重写原始for循环:

a_输出=0;
#ifdef\u OPENMP
#pragma omp并行默认值(无)\
二等兵(一)\
共享(n,t_输入,t0,跟踪放大器,a_输出)
#pragma omp for
#恩迪夫
对于(i=0;i=t0[i]){
a_输出=跟踪_amp[i];
#pragma omp cancel for
}
#pragma omp取消点
}
返回一个输出;
您必须将for
parallel
分开,以避免在for上使用隐式
nowait
子句

编辑:如@Zulan所述

1) 如果发生取消,则必须至少有一个所有线程都可以自然到达的取消点。尽管
cancel
指令本身根据定义有一个取消点,但它在一个if语句中,可能不是所有线程都可以访问该语句。解决方法是在if语句之外添加一个
取消点
。我更改了代码以与此匹配

2) 在大多数运行时默认情况下禁用取消。要启用,应将
OMP\u取消
环境变量设置为true


3)
a\u输出中仍然存在竞争条件。除非您确定
t0
中只有一个值小于
t\u input
,否则有可能在取消之前两个或多个线程将写入
a\u输出。您应该检查代码背后的逻辑,以确认这是否是一个问题。

您在询问之前询问过编译器吗?在循环中使用
return
语句会使程序不符合(OpenMP)由于您是从并行区域分支出来的。您必须在问题标题上更加具体:)感谢此解决方案。1)取消仅在取消点起作用(在您的示例中没有)。2)取消被defaut禁用,3)代码在
a_输出上仍有竞争条件。