For loop 平行';任务';在已经并行化的';对于';OpenMP中的循环

For loop 平行';任务';在已经并行化的';对于';OpenMP中的循环,for-loop,parallel-processing,task,openmp,For Loop,Parallel Processing,Task,Openmp,[背景:英特尔icc编译器上的OpenMP v4+] 我想在已经并行化的循环中并行化任务。我看到了很多关于这个主题的问题,例如: 还有更集中的智慧 但在尝试时,除了编译时的错误消息外,我无法得到明确的答案 代码: #pragma omp并行用于私有(a,bd)缩减(+:sum) 对于(int i=0;i循环工作共享构造中的单个工作共享构造是标准所禁止的,但您不需要它 通常的并行->单个->任务设置是为了确保您的任务有一个线程组设置(并行),但每个任务只生成一次(单个)。对于上下文,您不需

[背景:英特尔icc编译器上的OpenMP v4+]

我想在已经并行化的循环中并行化任务。我看到了很多关于这个主题的问题,例如:

  • 还有更集中的智慧
但在尝试时,除了编译时的错误消息外,我无法得到明确的答案

代码:

#pragma omp并行用于私有(a,bd)缩减(+:sum)

对于(int i=0;i循环工作共享构造中的单个工作共享构造是标准所禁止的,但您不需要它

通常的
并行
->
单个
->
任务
设置是为了确保您的任务有一个线程组设置(
并行
),但每个任务只生成一次(
单个
)。对于
上下文,您不需要在并行中使用后者,因为每个迭代只执行一次。因此,您可以直接在循环中生成任务。这似乎在gnu和英特尔编译器上都具有预期的行为,即已完成自己循环迭代的线程确实帮助其他线程执行其tasks

但是,在您的情况下,这是一个坏主意。与生成任务的开销相比,一个微小的计算,例如
sum1
本身会快得多

删除除的并行之外的所有pragma,这是一种非常合理的并行化。在进一步优化计算之前,您应该测量!特别是,您感兴趣的是,是否所有可用线程都在计算某个内容,或者某些线程是否提前完成并等待其他内容rs(负载不平衡)。要测量,您应该为您的平台寻找一个并行性能分析工具。如果是这种情况,您可以使用调度策略,或者可能通过内部循环中的嵌套并行来解决


对代码性能的全面讨论要复杂得多,需要详细的系统描述和实际测量的性能数字。

谢谢Zulan。你的解释肯定比编译时错误信息要好。根据你的指示,我将查看集群上的测量仪器。干杯,
 #pragma omp parallel for private(a,bd) reduction(+:sum)
    for (int i=0; i<128; i++) {
        a = i%2;
        for (int j=a; j<128; j=j+2) {
             u_n = 0.25 * ( u[ i*128 + (j-3) ]+
                            u[ i*128 + (j+3) ]+
                            u[ (i-1)*128 + j ]+
                            u[ (i+1)*128 + j ]);
          // #pragma omp single nowait 
          // {
          // #pragma omp task shared(sum1) firstprivate(i,j)
          // sum1 = (u[i*128+(j-3)]+u[i*128+(j-2)] + u[i*128+(j-1)])/3;
          // #pragma omp task shared(sum2) firstprivate(i,j)
          // sum2 = (u[i*128+(j+3)]+u[i*128+(j+2)]+u[i*128+(j+1)])/3; 
          // #pragma omp task shared(sum3) firstprivate(i,j)
          // sum3 = (u[(i-1)*128+j]+u[(i-2)*128+j]+u[(i-3)*128+j])/3;
          // #pragma omp task shared(sum4) firstprivate(i,j)
          // sum4 = (u[(i+1)*128+j]+u[(i+2)*128+j]+u[(i+3)*128+j])/3;
          // }
          // #pragma omp taskwait 
          // {
          // u_n = 0.25*(sum1+sum2+sum3+sum4);
          // }
             bd = u_n - u[i*128+ j];
             sum += diff * diff;
             u[i*128+j]=u_n;
       }    
  }