您的位置:首页 > 运维架构

OpenMP Tutorial学习笔记(5)OpenMP指令之共享工作构造(Work-Sharing)

2011-11-10 22:15 447 查看
OpenMP Tutorial:https://computing.llnl.gov/tutorials/openMP/#WorkSharing

共享工作构造:Work-Sharing Constructs

(1)Work-Sharing Constructs的特点和类型:

共享工作构造的基本特点:

1. 共享工作构造将它作用的代码段拆分到进入此区域的线程team的成员执行。

2. 共享工作构造不产生新的线程。

3. 进入共享工作区域不会有等待(barrier),退出共享工作构造的时候会有等待。
说明:barrier中文含义为“障碍”“关卡”,我个人觉得理解为“等待”更好,即同步的概念。

共享工作构造的类型:

1. do-for结构:



在一个team内,共享一个循环的迭代,代表“数据并行”的类型。

2. sections结构:



将任务分离为不同的sections,每一个section由一个线程执行。可用于实现“函数并行”的类型。

3. single结构:



将一段代码串行化。

共享并行结构的限制:

为了使得指令并行执行,共享工作结构必须被一个并行区域包围。

一个线程组到达一个工作共享结构时,要么全部全线程被占用,要么不占用。

线程组的所有成员必须以相同的顺序到达连续的工作共享结构。

(此处翻译参考自:/article/8148133.html,我目前还不太理解这几句话的真实含义)

(2)do-for指令

作用:指定之后的循环迭代由team内的线程并行执行,前提是已经使用parallel并行构造初始化(即被parallel块包围),否则在单处理器上串行执行。(那么多处理器呢?)下面是使用do-for指令的一个例子,并行执行for循环并打印for循环的条件变量,根据结果可以发现,在多核处理器上如果没有被parallel包围也是串行执行。

#define N	100	// 尽量让N大一点,否则无法说明问题

int main(int argc, char *argv[])
{
printf("Masterthread started\n\n");
printf("Using omp for\n");
#pragma omp for
for(int i = 0;i < N;i++)
{
printf("%d\n",i);
}// End of for region
printf("\n");

printf("Using omp parallel for\n");
#pragma omp parallel
{
#pragma omp for
for(int i = 0;i < N;i++)
{
printf("%d\n",i);
}// End of for region
}// End of parallel region

printf("Masterthread finished\n");

return(0);
}
下面介绍do-for指令的格式(说明的是,其实对于C++,称为for指令即可,之所以称为do-for指令是由于Fortran中是do关键字):

#pragma omp for [clause ...]  newline
schedule (type [,chunk])
ordered
private (list)
firstprivate (list)
lastprivate (list)
shared (list)
reduction (operator: list)
collapse (n)
nowait
for_loop
首先需要知道的是,for指令后必须紧接一个for循环,否则编译就会出错。

子句:

schedule:描述循环迭代是如何在线程之间划分的。默认的调度是依赖编译器的实现。schedule子句只用于for指令。

shedule可以取值为:STATIC、DYNAMIC、GUIDED、RUNTIME、AUTO。其区别在其它博文讨论。

nowait:如果指定了nowait,那么线程在并行循环结束处不进行同步。notwait不仅仅用于for指令(只要是共享工作构造都可以使用)。

ordered:指定该循环迭代必须以串行方式执行。

collapse:指定在一个嵌套循环中,多少次循环被折叠到一个大的迭代空间并根据schedule子句来划分。所有相关循环中的迭代的执行顺序决定迭代空间中折叠迭代的顺序。关于详细理解和schedule一起在其它博文讨论。

其它的一些子句,都是和数据相关的子句,后面会专门讨论。

for指令的主要限制:

循环控制变量必须是一个整数,而且循环控制参数对于所有线程必须是一样的。

程序的正确性不能依赖于哪个线程运行在某个具体的迭代上。

for循环中不能有分支(如goto)跳出循环。

(3)sections/section指令

作用:sections指令包含了多个section代码块,sections指令不是一个迭代的工作共享区域,而是每个section被一个线程执行一次,不同的section由不同的线程执行。一个线程也有可能执行多个section。

sections/section指令格式:

#pragma omp sections [clause ...]  newline
private (list)
firstprivate (list)
lastprivate (list)
reduction (operator: list)
nowait
{
#pragma omp section   newline
structured_block
#pragma omp section   newline
structured_block
}
sections块结束有一个隐含的等待,除非指定了nowait子句。其它的子句都是和数据相关,后面讨论。

问题:如果线程数和section数目不同?如果线程数大于section数的时候,那么有些线程执行一个section,有些线程不执行section;如果线程数小于sectioin数,那么可能某些线程要执行多个section,具体依赖于编译器的实现。包括哪个线程执行哪个section,也是依赖于编译器实现。

sections指令限制:

不能跳出(goto)一个section块;section必须出现在sections块内,没有孤立的sections块。

补充:sections指令和for指令应该一样,必须在parallel指令内,才会并行化,否则串行执行。下面是使用sections的一个简单例子:

int main(int argc, char *argv[])
{
printf("Masterthread started\n\n");

#pragma omp parallel
{
#pragma omp sections
{
#pragma omp section
{
printf("section 1\n");
}
#pragma omp section
{
printf("section 2\n");
}
#pragma omp section
{
printf("section 3\n");
}
#pragma omp section
{
printf("section 4\n");
}
}// End of sections region
}// End of parallel region

printf("Masterthread finished\n");

return(0);
}
(可以去掉parallel查看结果,会发现是串行执行的,只有使用parallel才会并行。)

(4)single指令

single指令作用:指定代码块由team内的一个线程执行,即相当于串行执行。主要可能用于使用sections的非线程安全的代码,比如IO处理等。

single指令格式:

#pragma omp single [clause ...]  newline
private (list)
firstprivate (list)
nowait
structured_block

默认情况下,不执行single指令的线程会在single块结尾处等待,除非使用了nowait。说明的是,single只是让team内的一个线程去执行这一段代码段,并不表示程序是单线程的,所以,如果不使用nowait,team内的其他线程都会等待着一个线程执行完毕。

下面的例子能帮助理解single的效果:

int main(int argc, char *argv[])
{
printf("Masterthread started\n\n");

#pragma omp parallel
{
#pragma omp single
{
printf("single block\n");
}// End of single region	// other threads will wait here except using nowait
printf("parallel block\n");
}// End of parallel region

printf("Masterthread finished\n");

return(0);
}


结果:



另外需要说明的是,single指令允许跳进或跳出(goto)代码块
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: