平行区域啥时候停止,哪个构造可以共享同一个平行区域?
Posted
技术标签:
【中文标题】平行区域啥时候停止,哪个构造可以共享同一个平行区域?【英文标题】:when does the parallel region stop and which construct can share the same parallel region?平行区域什么时候停止,哪个构造可以共享同一个平行区域? 【发布时间】:2015-02-15 06:08:10 【问题描述】:在实现我的openMP程序时被这两个问题困扰
Q1:平行区域和不同构造什么时候停止?
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
================================================ ======================= **Q2:哪些构造可以停留在同一个平行区域内? **
与第一个示例一样,#pragma omp for
和 #pragma omp master
默认情况下共享相同的并行区域,但是,#pragma omp master
之后的任何内容都不是即使没有明确说明这一点,什么样的构造可以共享相同的并行区域?比如工作共享结构与同步结构
对此有任何参考吗?
非常感谢!
【问题讨论】:
【参考方案1】:声明
#pragma omp parallel for reduction(+: t)
使用下一个 C 语句来定义工作区域。在该区域的开始处产生多个线程,并在该区域的结尾处集合。
#pragma omp master
和类似的方法将封闭区域分成几部分。该编译指示之后的部分仅由“主”线程运行。
并行区域内的“#for”使用由该区域定义的线程,它不定义区域本身,但定义了许多要执行的作业。除非添加了“nowait”子句,否则循环末尾会有一个“障碍”或同步点。使用 'nowait' 子句,循环之后的其他部分(例如 omp master)将同时运行。
强调一下,只要添加一个
#pragma omp parallel
你会得到多个线程。每个线程执行后的单个语句或块。需要另一个“#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");
【讨论】:
这并不能解释为什么例如,在#master 之后,printf() 只运行一次,表示并行停止 在您的示例中有两个原因(1)您的并行区域没有到达#master,因为它只包含一个语句,(2)即使它只有一个主线程,所以'#master' 部分仅由该线程运行一次。上面都提到了这两个。以上是关于平行区域啥时候停止,哪个构造可以共享同一个平行区域?的主要内容,如果未能解决你的问题,请参考以下文章