c - 并行区域何时停止以及哪个构造可以共享相同的并行区域?

标签 c parallel-processing openmp construct

在实现我的openMP程序时,很被这两个问题困扰

问题1:平行区域和不同构造什么时候停止?

OpenMP 似乎提倡使用 {} 作为构造或并行区域之间的分隔符,当与 for 循环使用的 {} 冲突或我们故意选择不使用它时,它有时会令人困惑或违背其初衷。代码简单

示例1:

int main() {
int i, j;
int t =0;
int a[sizeA];
for (i=0;i<sizeA;i++)
 a[i] =1;

 double elapsed =-omp_get_wtime();

 #pragma omp parallel for reduction(+: t)
  for(j=0; j<sizeA; j++)
    t=t+a[j];
  --------------------1-----------------------------------------------------
  #pragma omp master     
   printf("The sum of the array %d\n", t);

---------------------2-------------------------------------------------------
  elapsed+=omp_get_wtime();
  printf("The sum of the array In [REDUCTION] is %d: \n", t);
  printf("The time cost is %f: \n", elapsed);   
 -----------------------------3-------------------------------------- 
}

在上面的例子中,并行区域是停在1、2还是3处(如程序中所标记的)?根据测试结果,它停在位置2。因为2-3之间的部分只执行一次,我觉得这很困惑,为什么会这样呢?

我也非常反对使用组合指令,例如 #pragma omp parallel for bla bla,这让情况更加困惑,同样的代码,有点不同,添加了 {} for for 循环

   #pragma omp parallel for reduction(+: t)
  for(j=0; j<sizeA; j++)
  { //================difference added here================
    t=t+a[j];
    printf("hi, everyone\n");
  } //===============difference added here ==================

  //--------------------1-----------------------------------------------------
  #pragma omp master     
   printf("The sum of the array %d\n", t);

 //---------------------2-------------------------------------------------------
  elapsed+=omp_get_wtime();
  printf("The sum of the array In [REDUCTION] is %d: \n", t);
  printf("The time cost is %f: \n", elapsed);   
 // -----------------------------3-------------------------------------- 
}

在第二个示例中,并行区域是否停止于 1?在2?如果我想让并行区域包含 #pragma omp master 构造,是否必须为并行区域添加额外的括号?因此,打破组合指令#pragma omp parallel for,如下所示:或者有更好的方法(如果有的话,会非常高兴)

   #pragma omp parallel 
  {
    #pragma omp for reduction(+: t)
     for(j=0; j<sizeA; j++)
     { 
       t=t+a[j];
       printf("hi, everyone\n");
     } 

    #pragma omp master     
      bla bla
  }

================================================== ===================== **问题2:哪些类型的构造可以位于同一并行区域内? **

与第一个示例一样,#pragma omp for#pragma omp master 默认情况下共享相同的并行区域,但是,#pragma omp master 后面的任何内容都不是,即使没有明确说明这一点,什么样的构造可以共享同一个平行区域?就像工作共享结构与同步结构

有这方面的引用吗?

非常感谢!

最佳答案

声明

#pragma omp parallel for reduction(+: t)

使用下一个 C 语句来定义工作区域。在该区域的开始处生成多个线程,并在该区域的末尾处集合。

#pragma omp master

类似地将封闭区域划分为多个部分。该编译指示之后的部分仅由“主”线程运行。

并行区域中的“#for”使用该区域定义的线程,它不定义区域本身,而是定义要执行的许多作业。除非添加“nowait”子句,否则循环末尾会有“障碍”或同步点。使用“nowait”子句,循环后的其他部分(例如 omp master)将同时运行。

强调一下,一旦添加

#pragma omp parallel 

您将获得多个线程。每个线程执行后的单个语句或 block 。需要另一个“#pragma”来限制哪些线程运行代码的哪些部分。

编辑: 例如,在我的八核上,仅“Hello World”被打印八次。

#include <stdio.h>
#include <omp.h>
int main(){
  printf("Starting\n");
#pragma omp parallel
  printf("Hello World\n");
  printf("Split\n"); 
#pragma omp parallel
  {
#pragma omp master
    printf("OOps, really\n");
  }
  printf("Done\n");
}

关于c - 并行区域何时停止以及哪个构造可以共享相同的并行区域?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28523500/

相关文章:

c - 如何完全释放定时器(timer_list)?

使用 OpenMP 的 C++ 并行平均矩阵

java - 使 Parallel IntStream 更高效/更快?

c++ - 如何将 HEX 转换为 ASCII 字符串?

c - `return 1 + strlen_rec(&arr[1]) ;`是什么意思?

c - 如何在C中标记要选择的字符

parallel-processing - CUDA内核如何启动?

c - C中OpenMP中静态和动态调度的区别

c++ - OMP 目标中对全局数组(malloc 与静态)的不同处理

c++ - 在openmp中是只读的全局变量和写入私有(private)类成员 "false sharing"