OpenMP并行程序设计.ppt

上传人:牧羊曲112 文档编号:6513266 上传时间:2023-11-08 格式:PPT 页数:53 大小:335KB
返回 下载 相关 举报
OpenMP并行程序设计.ppt_第1页
第1页 / 共53页
OpenMP并行程序设计.ppt_第2页
第2页 / 共53页
OpenMP并行程序设计.ppt_第3页
第3页 / 共53页
OpenMP并行程序设计.ppt_第4页
第4页 / 共53页
OpenMP并行程序设计.ppt_第5页
第5页 / 共53页
点击查看更多>>
资源描述

《OpenMP并行程序设计.ppt》由会员分享,可在线阅读,更多相关《OpenMP并行程序设计.ppt(53页珍藏版)》请在三一办公上搜索。

1、OpenMP并行程序设计简介,华南理工大学 陈虎 博士,OpenMP概述,OpenMP应用编程接口API是在共享存储体系结构上的一个编程模型:包含编译制导(Compiler Directive),运行库例程(Runtime Library)和环境变量(Environment Variables)支持增量并行化(Incremental Parallelization),OpenMP历史,1994年,第一个ANSI X3H5草案提出,被否决1997年,OpenMP标准规范代替原先被否决的ANSI X3H5,被人们认可1997年10月公布了与Fortran语言捆绑的第一个标准规范 FORTRAN v

2、ersion 1.0 1998年11月9日公布了支持C和C+的标准规范C/C+version 1.0 2000年11月推出FORTRAN version 2.0 2002年3月推出C/C+version 2.0 2005年5月OpenMP2.5将原来的Fortran和C/C+标准规范相结合,OpenMP的优势,缺点,优势:相对简单。不需要显式设置互斥锁,条件变量,数据范围以及初始化。可扩展。主要是利用添加并行化指令到顺序程序中,由编译器完成自动并行化。移植性好。OpenMP规范中定义的制导指令、运行库和环境变量,能够使用户在保证程序的可移植性的前提下,按照标准将已有的串行程序逐步并行化,可以在

3、不同的产商提供的共享存储体系结构间比较容易地移植。,OpenMP的优势,缺点,缺点:程序的可维护性不够好当程序比较复杂的时候,编程会显得比较困难,OpenMP的支持环境,Intel等的C+和Fortran编译器Microsoft的Visual Studio 2005gcc4.2以上版本也宣布对其支持(尚未正式发布),OpenMP并行程序运行,并行区间(淡蓝色)表示该部分程序计算量大,需要多个处理器共同来处理以提高效率和运行速度并行区间以外的部分表示该部分的程序不适宜或者不能并行执行,只能由一个处理器来执行,OpenMP并行编程模型,OpenMP并行编程模型,基于线程的并行编程模型(Progra

4、mming Model)OpenMP使用Fork-Join并行执行模型,OpenMP程序设计,include#include“omp.h”Int main()#pragma omp parallel Printf(“hello world!n”);,程序的输出结果:hello world!hello world!hello world!,OpenMP程序结构,基于c/c+语言的OpenMP程序的结构#include main()int var1,var2,var3;/*Serial code*/*Beginning of parallel section.Fork a team ofthrea

5、ds*/*Specify variable scoping*/#pragma omp parallel private(var1,var2)shared(var3)/*Parallel section executed by all threads*/*All threads join master thread and disband*/*Resume serial code*/,编译制导,OpenMP的#pragma语句的格式为#pragma omp directive_name,编译制导,作用域静态扩展文本代码在一个编译制导语句之后,被封装到一个结构块中 孤立语句一个OpenMP的编译制

6、导语句不依赖于其它的语句 动态扩展 包括静态范围和孤立语句,作用域,并行域结构,并行域中的代码被所有的线程执行具体格式#pragma omp parallel clause,clausenewlineclause=if(scalar-expression)private(list)firstprivate(list)default(shared|none)shared(list)copyin(list)reduction(operator:list)num_threads(integer-expression),共享任务结构,共享任务结构将它所包含的代码划分给线程组的各成员来执行并行for循环

7、并行sections串行执行,for编译制导语句,for语句指定紧随它的循环语句必须由线程组并行执行;语句格式#pragma omp for clause,clause newlineclause=Schedule(type,chunk)orderedprivate(list)firstprivate(list)lastprivate(list)shared(list)reduction(operator:list)nowait,for编译制导语句,schedule子句描述如何将循环的迭代划分给线程组中的线程如果没有指定chunk大小,迭代会尽可能的平均分配给每个线程type为static,循

8、环被分成大小为 chunk的块,静态分配给线程type为dynamic,循环被动态划分为大小为chunk的块,动态分配给线程,Sections编译制导语句,sections编译制导语句指定内部的代码被划分给线程组中的各线程不同的section由不同的线程执行Section语句格式:#pragma omp sections clause,clause newline#pragma omp section newline#pragma omp section newline,Sections编译制导语句,clause=private(list)firstprivate(list)lastpriva

9、te(list)reduction(operator:list)nowait 在sections语句结束处有一个隐含的路障,使用了nowait子句除外,Sections编译制导语句,#include/eg2#define N 1000int main()int i;float aN,bN,cN;/*Some initializations*/for(i=0;i N;i+)ai=bi=i*1.0;#pragma omp parallel shared(a,b,c)private(i)#pragma omp sections nowait#pragma omp section for(i=0;i

10、N/2;i+)ci=ai+bi;#pragma omp section for(i=N/2;i N;i+)ci=ai+bi;/*end of sections*/*end of parallel section*/,single编译制导语句,single编译制导语句指定内部代码只有线程组中的一个线程执行。线程组中没有执行single语句的线程会一直等待代码块的结束,使用nowait子句除外语句格式:#pragma omp single clause,clause newlineclause=private(list)firstprivate(list)nowait,组合的并行共享任务结构,pa

11、rallel for编译制导语句parallel sections编译制导语句,同步结构,master 制导语句critical制导语句barrier制导语句atomic制导语句flush制导语句ordered制导语句,master 制导语句,master制导语句指定代码段只有主线程执行语句格式#pragma omp master newline,critical制导语句,critical制导语句表明域中的代码一次只能执行一个线程 其他线程被阻塞在临界区语句格式:#pragma omp critical name newline,critical制导语句,#include main()int

12、x;x=0;#pragma omp parallel shared(x)#pragma omp critical x=x+1;/*end of parallel section*/,barrier制导语句,barrier制导语句用来同步一个线程组中所有的线程先到达的线程在此阻塞,等待其他线程barrier语句最小代码必须是一个结构化的块语句格式#pragma omp barrier newline,barrier制导语句,barrier正确与错误使用比较,atomic制导语句,atomic制导语句指定特定的存储单元将被原子更新语句格式#pragma omp atomic newline ato

13、mic使用的格式,flush制导语句,flush制导语句用以标识一个同步点,用以确保所有的线程看到一致的存储器视图语句格式#pragma omp flush(list)newline flush将在下面几种情形下隐含运行,nowait子句除外,barriercritical:进入与退出部分ordered:进入与退出部分parallel:退出部分for:退出部分sections:退出部分single:退出部分,ordered制导语句,ordered制导语句指出其所包含循环的执行任何时候只能有一个线程执行被ordered所限定部分只能出现在for或者parallel for语句的动态范围中语句格式

14、:#pragma omp ordered newline,threadprivate编译制导语句,threadprivate语句使一个全局文件作用域的变量在并行域内变成每个线程私有每个线程对该变量复制一份私有拷贝语句格式:#pragma omp threadprivate(list)newline,threadprivate编译制导语句,int alpha10,beta10,i;/eg3#pragma omp threadprivate(alpha)int main()/*First parallel region*/#pragma omp parallel private(i,beta)fo

15、r(i=0;i 10;i+)alphai=betai=i;/*Second parallel region*/#pragma omp parallel printf(alpha3=%d and beta3=%dn,alpha3,beta3);,数据域属性子句,变量作用域范围数据域属性子句private子句shared子句default子句firstprivate子句lastprivate子句copyin子句reduction子句,private子句,private子句表示它列出的变量对于每个线程是局部的。语句格式private(list)private和threadprivate区别,shar

16、ed子句,shared子句表示它所列出的变量被线程组中所有的线程共享所有线程都能对它进行读写访问语句格式shared(list),default子句,default子句让用户自行规定在一个并行域的静态范围中所定义的变量的缺省作用范围语句格式default(shared|none),firstprivate子句,firstprivate子句是private子句的超集对变量做原子初始化语句格式:firstprivate(list),lastprivate子句,lastprivate子句是private子句的超集将变量从最后的循环迭代或段复制给原始的变量语句格式lastprivate(list),c

17、opyin子句,copyin子句用来为线程组中所有线程的threadprivate变量赋相同的值主线程该变量的值作为初始值语句格式copyin(list),reduction子句,reduction子句使用指定的操作对其列表中出现的变量进行规约初始时,每个线程都保留一份私有拷贝在结构尾部根据指定的操作对线程中的相应变量进行规约,并更新该变量的全局值语句格式reduction(operator:list),reduction子句,#include/eg4int main()int i,n,chunk;float a100,b100,result;/*Some initializations*/n

18、=100;chunk=10;result=0.0;for(i=0;i n;i+)ai=i*1.0;bi=i*2.0;,#pragma omp parallel for default(shared)private(i)schedule(static,chunk)reduction(+:result)for(i=0;i n;i+)result=result+(ai*bi);printf(Final result=%fn,result);,reduction子句,Reduction子句的格式,x=x op exprx=expr op x(except subtraction)x binop=exp

19、rx+xx-x,x是一个标量expr是一个不含对x引用的标量表达式,且不被重载binop是+,*,-,/,&,|之一,且不被重载op是+,*,-,/,&,|,&,or|之一,且不被重载,子句/编译制导语句总结,语句绑定和嵌套规则,语句绑定语句DO/for、SECTIONS、SINGLE、MASTER和BARRIER绑定到动态的封装PARALLEL中,如果没有并行域执行,这些语句是无效的;语句ORDERED指令绑定到动态DO/for封装中;语句ATOMIC使得ATOMIC语句在所有的线程中独立存取,而并不只是当前的线程;语句CRITICAL在所有线程有关CRITICAL指令中独立存取,而不是只对

20、当前的线程;在PARALLEL封装外,一个语句并不绑定到其它的语句中。,语句绑定和嵌套规则,语句嵌套PARALALL 语句动态地嵌套到其它地语句中,从而逻辑地建立了一个新队列,但这个队列若没有嵌套地并行域执行,则只包含当前的线程;DO/for、SECTION和SINGLE语句绑定到同一个PARALLEL 中,则它们是不允许互相嵌套的;DO/for、SECTION和SINGLE语句不允许在动态的扩展CRITICAL、ORDERED和MASTER域中;CRITICAL语句不允许互相嵌套;BARRIER语句不允许在动态的扩展DO/for、ORDERED、SECTIONS、SINGLE、MASTER和

21、CRITICAL域中;MASTER语句不允许在动态的扩展DO/for、SECTIONS和SINGLE语句中;ORDERED语句不允许在动态的扩展CRITICAL域中;任何能允许执行到PARALLEL 域中的指令,在并行域外执行也是合法的。当执行到用户指定的并行域外时,语句执行只与主线程有关。,运行库例程与环境变量,运行库例程OpenMP标准定义了一个应用编程接口来调用库中的多种函数 对于C/C+,在程序开头需要引用文件“omp.h”环境变量OMP_SCHEDULE:只能用到for,parallel for中。它的值就是处理器中循环的次数 OMP_NUM_THREADS:定义执行中最大的线程数O

22、MP_DYNAMIC:通过设定变量值TRUE或FALSE,来确定是否动态设定并行域执行的线程数OMP_NESTED:确定是否可以并行嵌套,OpenMP计算实例,矩形法则的数值积分方法估算Pi的值,原始串行程序,/*Seriel Code*/static long num_steps=100000;double step;void main()int i;double x,pi,sum=0.0;step=1.0/(double)num_steps;for(i=0;i num_steps;i+)x=(i+0.5)*step;sum=sum+4.0/(1.0+x*x);pi=step*sum;,Op

23、enMP计算实例,#include static long num_steps=100000;double step;#define NUM_THREADS 2 void main()int i;double x,pi,sumNUM_THREADS;step=1.0/(double)num_steps;omp_set_num_threads(NUM_THREADS);#pragma omp parallel double x;int id=omp_get_thread_num();for(i=id,sumid=0.0;i num_steps;i=i+NUM_THREADS)x=(i+0.5)*

24、step;sumid+=4.0/(1.0+x*x);for(i=0,pi=0.0;iNUM_THREADS;i+)pi+=sumi*step;,使用共享任务结构,#include static long num_steps=100000;double step;#define NUM_THREADS 2 void main()int i;double x,pi,sumNUM_THREADS;step=1.0/(double)num_steps;omp_set_num_threads(NUM_THREADS);#pragma omp parallel double x;int id;id=omp

25、_get_thread_num();sumid=0;/*#pragma omp for/*for(i=0;i num_steps;i+)x=(i+0.5)*step;sumid+=4.0/(1.0+x*x);for(i=0,pi=0.0;iNUM_THREADS;i+)pi+=sumi*step;,使用private和critical,#include static long num_steps=100000;double step;#define NUM_THREADS 2 void main()int i;double x,sum,pi=0.0;step=1.0/(double)num_s

26、teps;omp_set_num_threads(NUM_THREADS)#pragma omp parallel private(x,sum)id=omp_get_thread_num();for(i=id,sum=0.0;i num_steps;i=i+NUM_THREADS)x=(i+0.5)*step;sum+=4.0/(1.0+x*x);#pragma omp critical pi+=sum,使用并行归并,#include static long num_steps=100000;double step;#define NUM_THREADS 2 void main()int i;double x,pi,sum=0.0;step=1.0/(double)num_steps;omp_set_num_threads(NUM_THREADS)#pragma omp parallel for reduction(+:sum)private(x)for(i=0;inum_steps;i+)x=(i+0.5)*step;sum=sum+4.0/(1.0+x*x);pi=step*sum;,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号