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包围也是串行执行。
子句:
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指令格式:
问题:如果线程数和section数目不同?如果线程数大于section数的时候,那么有些线程执行一个section,有些线程不执行section;如果线程数小于sectioin数,那么可能某些线程要执行多个section,具体依赖于编译器的实现。包括哪个线程执行哪个section,也是依赖于编译器实现。
sections指令限制:
不能跳出(goto)一个section块;section必须出现在sections块内,没有孤立的sections块。
补充:sections指令和for指令应该一样,必须在parallel指令内,才会并行化,否则串行执行。下面是使用sections的一个简单例子:
(4)single指令
single指令作用:指定代码块由team内的一个线程执行,即相当于串行执行。主要可能用于使用sections的非线程安全的代码,比如IO处理等。
single指令格式:
默认情况下,不执行single指令的线程会在single块结尾处等待,除非使用了nowait。说明的是,single只是让team内的一个线程去执行这一段代码段,并不表示程序是单线程的,所以,如果不使用nowait,team内的其他线程都会等待着一个线程执行完毕。
下面的例子能帮助理解single的效果:
结果:
另外需要说明的是,single指令允许跳进或跳出(goto)代码块。
共享工作构造: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)代码块。
相关文章推荐
- OpenMP Tutorial学习笔记(6)OpenMP指令之组合共享工作构造(Combined Work-Sharing)
- OpenMP Tutorial学习笔记(7)OpenMP指令之任务构造(Task Constructs)
- OpenMP 并行区域之间的工作共享方法
- OpenMP Tutorial学习笔记(8)OpenMP指令之同步构造(Synchronization Constructs)
- OpenMP Tutorial学习笔记(4)OpenMP指令之同步构造(Parallel)
- 第三章 3.2 文件共享入门简介 Introduction of File Sharing System
- 工作队列&nbsp;work_struct&nbsp;&amp;…
- 工作安排(Work scheduling,2009 Open)
- 海南英语111——Part 4:Talking about Work 谈论工作
- Lazy Analytics Let Other Queries Do the Work For You 懒惰分析:让其他查询语句为你工作
- ArcGIS Engine代码共享-工作空间(workspace)对象操作
- linux工作队列 - 把work_struct加入工作队列
- 跨应用程序共享session Sharing Session Across Applications
- Adaptive Collaborative Work(ACW) 自适应协同工作 109 of 281 and Software as a Service(202)
- 工作队列(workqueue) create_workqueue/schedule_work/queue_work
- 科研经验2:云协作建立实验室工作总结和内部资料共享平台
- 工作队列分析 queue_work
- AxonFramework工作单元,The Unit of Work
- 工作队列分析 queue_work
- WorkList工作笔记