机群应用开发并行编程原理及程序设计ParallelProgramming

上传人:re****.1 文档编号:567917883 上传时间:2024-07-22 格式:PPT 页数:108 大小:581.01KB
返回 下载 相关 举报
机群应用开发并行编程原理及程序设计ParallelProgramming_第1页
第1页 / 共108页
机群应用开发并行编程原理及程序设计ParallelProgramming_第2页
第2页 / 共108页
机群应用开发并行编程原理及程序设计ParallelProgramming_第3页
第3页 / 共108页
机群应用开发并行编程原理及程序设计ParallelProgramming_第4页
第4页 / 共108页
机群应用开发并行编程原理及程序设计ParallelProgramming_第5页
第5页 / 共108页
点击查看更多>>
资源描述

《机群应用开发并行编程原理及程序设计ParallelProgramming》由会员分享,可在线阅读,更多相关《机群应用开发并行编程原理及程序设计ParallelProgramming(108页珍藏版)》请在金锄头文库上搜索。

1、机群应用开发并行编程原理及并行编程原理及程序设计程序设计Parallel Programming: Parallel Programming: Fundamentals and ImplementationFundamentals and Implementation戴戴戴戴 荣荣荣荣曙光信息产业有限公司曙光信息产业有限公司曙光信息产业有限公司曙光信息产业有限公司2006.42006年4月1共享存储编程参考文献z黄铠,徐志伟著,陆鑫达等译. 可扩展并行计算技术可扩展并行计算技术,结构与编程结构与编程. 北京:机械工业出版社, P.3356,P.227237, 2000.z陈国良著.并行计算并行

2、计算结结构、算法、编程构、算法、编程. 北京:高等教育出版社,1999.zBarry Wilkinson and Michael Allen. Parallel Programming(Techniques and Applications using Networked Workstations and Parallel Computers). Prentice Hall, 1999.z李晓梅,莫则尧等著. 可扩展并行算法的设计与分析可扩展并行算法的设计与分析. 北京:国防工业出版社,2000.z张宝琳,谷同祥等著. 数值并行计算原理与方法数值并行计算原理与方法. 北京:国防工业出版社,19

3、99.z都志辉著. 高性能计算并行编程技术高性能计算并行编程技术MPI并并行程序设计行程序设计. 北京:清华大学出版社, 2001. 2006年4月2共享存储编程相关网址zMPI: http:/ww.mpi-forum.org, http:/www.mcs.anl.gov/mpizPthreads: http:/zPVM: http:/www.epm.ornl.gov/pvm/ zOpemMP: http:/www.openmp.orgz网上搜索:2006年4月3共享存储编程共享存储编程共享存储编程Programming with Shared Programming with Shared

4、MemoryMemory2006年4月4共享存储编程共享存储并行机模型体系结构特点体系结构特点:多台处理机通过互联网络共享一个统一的内存空间,通过单一内存地址单一内存地址来实现处理机间的协调.内存空间也可由多个存储器模块构成.每台处理机可以执行相同或不同的指令流,每台处理机可以直接访问到所有数据.处理机间通信是借助于共享主存来通信是借助于共享主存来实现的实现的.可扩展性差,当处理机需要同时访问共享全局变量时,产生内存竞争现象而严重影响效率,比较适合中小规模应用问题的计算和事务处理.2006年4月5共享存储编程共享存储编程标准与特点z共享存储器编程标准yPthreads(线程标准) yX3H5(

5、线程标准)yOpenMP(最常用的共享存储并行编程方式,是我们讨论的重点.)z共享存储器编程特点y显式多线程库调用.(Pthreads).y编译制导语句,OpenMP等.z语言yC,Fortran77,Fortran90/95,C+2006年4月6共享存储编程并行编程标准z线程库线程库标准标准(Thread Library)y Win32 API.y POSIX threads线程模型线程模型.y X3H5:概念性线程模型z编译制导编译制导(Compiler Directives)y OpenMP - portable shared memory parallelism.2006年4月7共享存

6、储编程为什么流行多线程编程?z线程线程:在进程的内部执行的指令序列.z相对于进程,线程开销小:y创建一个线程的时间大约是建立一个新进程的1/30。如在Sun4/75工作上站上,创建一个非绑定线程约为52微秒,而fork()一次的时间为1700微秒。y线程同步时间约是进程同步时间的1/3.z线程与RPC相结合,发挥多处理机的处理能力;z发挥多处理器的处理能力;z开发程序的并发性,改善程序的结构.z容易实现数据共享:由于线程共用内存地址,因此可实现数据共享y例:一高性能Web服务器可为每一打开链接的浏览器分配一个线程,所有线程即可共用同一cache来访问网站的热点话题z统一的标准:y以前各开发商提

7、供互不兼容的线程库,结果导致多线程程序不能很好地移值。自1995年的POSIX线程标准实施之后,极大地促进多线程编程的统一。各系统都支持Pthreads,如Linux、SUN、IBM AIX等。2006年4月8共享存储编程Pthreads线程模型zPOSIX1003.4a小组研究多线程编程标准. 当标准完成后,大多数支持多线程的系统都支持POSIX接口.很好的改善了多线程编程的可移植性.zIEEE Portable Operating System Interface, POSIX, 1003.1-1995标准:POSIX线程模型:pthreads.2006年4月9共享存储编程线程管理(Pth

8、read为例)z创建:pthread_createz终止:pthread_exitz汇合:pthread_joinz分离:pthread_detachz线程属性初始化:pthread_attr_initz唯一执行:pthread_once2006年4月10共享存储编程同步对象z在共享存储多处理器并行机上,线程通过全局变量通信,对于全局变量的操作必须进行同步。zpthread提供两个线程同步原语 : 互斥和条件变量.2006年4月11共享存储编程互斥锁函数 函数函数 操作操作Mutex_init() 初始化一个互斥锁Mutext_lock() 阻塞式加锁操作Mutex_trylock() 非阻塞

9、式加锁操作Mutex_unlock() 解锁Mutex_destroy() 解除互斥状态2006年4月12共享存储编程条件变量的函数 函数函数 操作操作pthread_cond_init() 初始化条件变量pthread_cond_wait() 阻塞直至条件为真pthread_cond_signal() 强制条件为真,解除等待条件的线程的阻塞pthread_cond_timedwait() 阻塞直到指定条件为真或timeoutpthread_cond_broadcast()解除所有等待条件的线程的阻塞pthread_cond _destroy() 销毁条件变量 2006年4月13共享存储编程H

10、ello World(1)#include #include stdio.hvoid *worker();main()pthread_t thread;pthread_create(&thread,NULL,worker,NULL);pthread_join(thread,NULL);void *worker()printf(Hello World!n);编译编译命令命令gcc hello.c lpthread运行结果运行结果Hello World!2006年4月14共享存储编程zpthread_t 线程数据类型zpthread_create(&thread,NULL,worker,NULL)

11、;y函数pthread_create()用于创建一新的线程,新线程一旦建立便进入运行状态y参数:x线程指针或句柄x线程属性变量,属性参数:默认为NULL. 属性对象一旦建立可以用于创建多个具有共同属性的线程,线程创建后,可删除属性对象.x线程要执行的函数x传入该执行函数的一个参数,无则NULL.可以是任意类型z线程的终止y线程函数正常终止返回;y自调用pthear_exit()函数;y线程被取消;y线程接收到中止的信号;y当主进程执行exit()后,进程及其全部线程全部终止.2006年4月15共享存储编程zpthread_join(pthread_t wait_for,void* status

12、); y等待直到线程结束;y执行该函数的线程发生阻塞,直到由wait_for指定的线程终止; y等与被等的两线程必须是同一进程内部的线程(而且不是分离线程);y返回值x0成功返回xESRCH参数wait_for指定的线程不存在或是一分离线程;xEINVAL线程参数无效;xEDEADLK 等待自身结束.y不能有两个线程同时等待同一个线程的结束, 否则其中一个线程正常返回,另外一个返回ESRCH错误.2006年4月16共享存储编程Hello World(2)#include #include stdio.h#define numthrds 5pthread_t *tid;void *worker(

13、);main()int i;tid = (pthread_t*) calloc(numthrds,sizeof(pthread_t);for(i=0;inumthrds;i+) pthread_create(&tidi,NULL,worker,NULL);for(i=0;inumthrds;i+) pthread_join(tidi,NULL);void *worker() int myid; myid = pthread_self() - tid0; printf(Hello World from thread %d!n,myid); Hello World from thread 0!He

14、llo World from thread 1!Hello World from thread 2!Hello World from thread 3!Hello World from thread 4!2006年4月17共享存储编程Hello World(3)#include #include stdio.h#define numthrds 5pthread_t *tid;pthread_mutex_t mutex;int sum=0;void *worker();main()int i;tid = (pthread_t*) calloc(numthrds,sizeof(pthread_t)

15、;pthread_mutex_init(&mutex,NULL);for(i=0;inumthrds;i+) pthread_create(&tidi,NULL,worker,NULL);for(i=0;inumthrds;i+) pthread_join(tidi,NULL);printf(“The sum is %dn,sum);void *worker() int myid,num; myid = pthread_self() - tid0; printf(%d was added to the sum in thread %dn,myid*10,myid); pthread_mutex

16、_lock(&mutex);sum += myid*10;pthread_mutex_unlock(&mutex);return;2006年4月18共享存储编程运行结果运行结果0 was added to the sum in thread 010 was added to the sum in thread 120 was added to the sum in thread 230 was added to the sum in thread 340 was added to the sum in thread 4The sum is 1002006年4月19共享存储编程基于多线程编程的P

17、I求解222006年4月20共享存储编程#include #include stdio.hpthread_mutex_t reduction_mutex;pthread_t *tid;double pi,w;int n;int num_threads;double f(a)double a; return (4.0/(1.0 + a*a);void *PIworker(void* arg) int i,myid; double sum,mypi,x; /*set individual id to start at 0 */ myid = pthread_self() - tid0; /*int

18、egrate function*/ sum=0.0; for(i = myid + 1;i = n; i+=num_threads) x = w * (double)i - 0.5); sum += f(x); mypi = w * sum; /*reduce value*/ pthread_mutex_lock(&reduction_mutex); pi += mypi; pthread_mutex_unlock(&reduction_mutex); return(0);2006年4月21共享存储编程void main(argc,argv)int argc;char* argv; int i

19、; /*check command line */ if(argc != 3) printf(Usage: %s Num_intervals Num_threadsn,argv0); exit(0); /*get num intervals and num threads from command line*/ n = atoi(argv1); num_threads = atoi(argv2); w = 1.0 / (double)n; pi = 0.0; tid = (pthread_t*) calloc (num_threads,sizeof(pthread_t);/*initilize

20、 lock*/if(pthread_mutex_init(&reduction_mutex,NULL) fprintf(stderr,Cannot init lockn); exit(1);/*create the threads*/ for(i = 0; inum_threads; i+)if(pthread_create(&tidi,NULL,PIworker,NULL) fprintf(stderr,Cannot create thread %dn,i); exit(1); /*join threads*/ for(i = 0; i num_threads; i+) pthread_jo

21、in(tidi,NULL); printf(computed pi = %.16fn,pi);gcc hello.c lpthread a.out 1000 5computed pi = 3.1415927369231271转去Openmp2006年4月22共享存储编程多线程并行编程特点zpthread_create()创建一个新线程比重新启动一个线程花费的时间少: 需要时创建+任务结束立刻杀掉 vs. 维护一大堆的空闲线程并且相互切换.z在加锁的前提下访问共享资源z不支持数据并行不支持数据并行,适合于任务级并行,即一个线程单独执行一个任务;z不支持增量并行化,对于一个串行程序,很难用Pthr

22、eads进行并行化zPthreads主要是面向操作系主要是面向操作系统统, 而不是而不是为为高性能高性能计计算算设计设计的的,因此不因此不是并行是并行计计算程序算程序设计设计的主流平台的主流平台。但是但是“多多线线程并程并发执发执行行”这这种思想却种思想却被广泛地被广泛地应应用于高性能用于高性能计计算算。这这就是我就是我们们即将要即将要讲讲的共享存的共享存储储并行并行编编程的另外一种被并行机制造商和广用并行程的另外一种被并行机制造商和广用并行计计算用算用户户广泛接受的平台广泛接受的平台:OpenMP2006年4月23共享存储编程并行编程标准z线程库线程库标准标准(Thread Library)

23、y Win32 API.y POSIX threads线程模型线程模型.y X3H5:概念性线程模型概念性线程模型z编译制导编译制导(Compiler Directives)y OpenMP - portable shared memory parallelism.2006年4月24共享存储编程www.openmp.orgAn Industry Standard API for Shared Memory ProgrammingAn API for Writing Multithreaded Applications一系列编译制导语句和库函数使得Fortran, C and C+的多线程编程更

24、加容易的多线程编程更加容易2006年4月25共享存储编程与X3H5的关系zX3H5是ANSI/X3授权的小组委员会,主要目的是在PCF(the Parallel Computing Forum)工作的基础上,发展并行计算的一个ANSI标准. PCF是一非正式的工业组织,虽在DO循环的并行化方法的标准化方面做一些工作,但在起草拟了一个标准后就草草收场.zOpenMP专门针对这类并行化问题,并完成了这项工作,同时得到工业界的广泛支持.2006年4月26共享存储编程ANSI X3H5共享编程标准z概念性的编程模型(ANSI标准(1993)y没有任何商品化的共享存储器系统依附于X3H5,但X3H5的基

25、本概念影响以后共享存储器系统的并行编程.(一些基本概念在OpenMP均出现!)zX3H5支持C,Fortran77以及Fortran90语言.zX3H5规定的基本的并行结构用于并行性表述:y并行块(分散任务Work Sharing)y并行循环y单进程parallel end parallelpsections end psectionspdoend pdopsingleend psingle2006年4月27共享存储编程X3H5编程实例program main !程序以顺序模式执行A!A只由基本线程执行parallel!转换成并行模式B!B为每个组员所复制psections!并行块开始sect

26、ionC!一个组员执行CsectionD!另一个组员执行Dend psections!等待C和D都结束psingle暂时转换成顺序模式E!E只能被一个组员执行end psingle!转回并行模式pdo I=1,6!并行do循环开始F(i)!各线程分担循环任务end pdo no wait!无隐式路障同步G!更多的复制代码end parallel!结束并行模式H!根进程执行H!更多的并行构造zend线程PQRBBECF(1:2)F(3:4) F(5:6)GGGH隐式barrier隐式barrier隐式barrier无隐式barrier隐式barrierBD各线程以负载平衡方式分担任务可能为:F(

27、1:1),F(2:2),F(3:6)2006年4月28共享存储编程X3H5例程执行过程描述z程序以顺序方式启动,此时只有一个初始化线程,称为基本线程或主线程.当程序遇到parallel时,通过派生多个子线程转换为并行执行模式(线程数隐式决定).基本线程与它的子线程形成一个组.所有组员并行处理后继并行代码,直至end parallel.然后程序转为顺序模式,只有基本线程继续执行.z子线程遇到内部并行或任务分担构造时,可以继续派生其子线程,从而成为一个新组的基本线程.z线程间同步,通信与交互y隐式路障:parallel, end parallel, end pdo或end psingle处隐式ba

28、rrier.如果不需,则加no wait;y各处理机通过全局变量通信,通过私有变量封装数据 fork. barrier顺序执行顺序执行并行执行2006年4月29共享存储编程OpenMP: 并行模型并行模型zFork-Join 并行模式:y主线程根据需要创建一组子线程进行工作分担.y可对串行程序进行逐步并行化.主线程主线程并行执行区域并行执行区域2006年4月30共享存储编程如何应用OpenMP?zOpenMP常用于循环并行化常用于循环并行化:y 找出最耗时的循环.y 将循环由多线程完成.y在串行程序上加上编译制导语句在串行程序上加上编译制导语句,完成并行化完成并行化,因此可先完成串行因此可先完

29、成串行程序程序,然后再进行然后再进行OpenMP并行化并行化.void main() double Res1000; for(int i=0;i1000;i+) do_huge_comp(Resi); void main() double Res1000; #pragma omp parallel for for(int i=0;i1000;i+) do_huge_comp(Resi);串行程序并行程序用用OpenMP将该循环通过多线程进行任务分割将该循环通过多线程进行任务分割2006年4月31共享存储编程线程间如何交互?zOpenMP 是基于共享内存模型.y线程通过共享变量通信.z访问共享变

30、量会导致race condition (竞态状态)yrace condition:是一种状态,在这种状态下两个实体(例如两个处理过程)对同一资源进行竞争,而系统没有一种机制来测定首先要执行的是哪一个。因此,由于系统不能保证数据的正确处理,其结果是不可预测的。z为了避免线程进入竞态状态:y通过同步对象来保护数据冲突.2006年4月32共享存储编程OpenMP术语z大多大多OpenMP构造是制导语句或构造是制导语句或pragmas.yC和和C+的的pragmas形式为形式为:x#pragma omp construct clause clauseyFortran中中,制导语句形式为以下几种制导语句

31、形式为以下几种:xC$OMP CONSTRUCT clause clausex!$OMP CONSTRUCT clause clause(自由书写格式唯一)x*$OMP CONSTRUCT clause clausex例:以下三种等价(第一行为列数)xC23456789x!$OMP PARALLEL DO SHARED(A,B,C)xC$OMP PARALLEL DOxC$OMP+SHARED(A,B,C)xC$OMP PARALLELDOSHARED(A,B,C)z由于由于OpenMP构造为注释性语句构造为注释性语句,因此一个因此一个OpenMP程序在用不支持程序在用不支持OpenMP的编译

32、器编译后的编译器编译后,仍为串行程序仍为串行程序.2006年4月33共享存储编程Structured blocks(结构化块)z结构化块性质:y仅在块顶有一个入口和块底有一个出口;y块功能可通过构造的语法清晰地识别;y块内除Fortran中的STOP语句和c/c+中的exit()语句外,不能有其它分支.z大多大多OpenMP构造为构造为结构化块.C$OMP PARALLEL10 if() goto 10C$OMP END PARALLELprint *,idC$OMP PARALLEL10 30if() goto 20go to 10C$OMPEND PARALLELif() goto 302

33、0print *, id一个结构化块一个非结构化块2006年4月34共享存储编程OpenMP结构化块类型zOpenMP主要有五类结构化块:y并行区Parallel Regionsy任务分割Worksharingy数据环境Data Environmenty同步同步Synchronizationy运行时函数运行时函数/环境变量z在Fortran,C/C+中,OpenMP基本上是一样的.2006年4月35共享存储编程Parallel Regions(并行区)z并行区是OpenMP的基本构造,并行区内的代码由各线程同时执行.z当一个线程执行“omp parallel”后,建立一组线程,该线程成为新建立

34、的线程组的主线程.所有线程构成一线程组,各线程以线程ID区分,主线程ID为0.z线程组并行执行并行区内代码.z如:建立一个4线程的并行区:double A1000;omp_set_num_threads(4);#pragma omp parallel int ID = omp_thread_num(); worker(ID,A);每一线程以不同的线程ID和相同的参数A执行并行区内代码的一拷贝.ID(=0,1,2,3).2006年4月36共享存储编程并行区的并行区的LecicalLecical / dynamic extent / dynamic extent以及以及Orphaned Orpha

35、ned 制所语句制所语句bar.fsubroutine whoamiexternal omp_get_thread_numinteger iam, omp_get_thread_numiam = omp_get_thread_num()C$OMP CRITICALprint*,Hello from , iamC$OMP END CRITICALreturnendpoo.fC$OMP PARALLELcall whoamiC$OMP END PARALLELStatic/lexical extent:在书写上直接包含在并行区内的部分.+Dynamic extent:包括并行区内直接和间接(函数调

36、用)包含的内容,也被称为region.Orphan制导语句:落在子程序中的制导语句,方便于子程序的并行化,免去传统的inline处理2006年4月37共享存储编程并行区代码流程double A1000;omp_set_num_threads(4);#pragma omp parallel int ID = omp_thread_num(); worker(ID,A);opm_set_num_threads(4)worker(2,A)worker(1,A)worker(3,A)Double A1000worker(0,A)所有线程在此处同步(如,隐式barrier同步)每一线程执行相同代码,不同

37、数据.所以,并行区结构也被称为SPMD结构.2006年4月38共享存储编程Hello World(C)#include main() int myid,numthreads; #pragma omp parallel myid = omp_get_thread_num(); numthreads = omp_get_num_threads(); printf(Hello World from thread %d of %d!n,myid,numthreads); 2006年4月39共享存储编程Hello World(Fortran) PROGRAM HELLO integer myid,num

38、threads integer omp_get_num_threads,omp_get_thread_num!$omp parallel private(numthreads,myid) numthreads = omp_get_num_threads() myid = omp_get_thread_num() print *, Hello World from thread ,myid,of,numthreads!$omp end parallel stop end2006年4月40共享存储编程OpenMP并行程序编译支持编译OpenMP的编译器会提供编译器命令选项,以解释OpenMP编译制

39、导语句.IBM AIX xlc编译器,编译器命令选项为-qsmpxlc file.c qsmpxlf_r file.f -qsmp (xlf_r为IBM AIX4.3为支持多线程编程的编译器)曙光3000:OS: AIX4.3 -qsmp AIX4.3支持 OpenMP编译选项Intel C/C+编译器icc, Intel Fortran编译器选项为-openmpicc file.c openmpifc file.f openmp曙光4000L:OS:Redhat Linux 8.0PGI C/C+编译器icc, PGI Fortran编译器选项为-mppgcc file.c mppgf77

40、file.f mppgf90 file.f mp曙光4000A:OS:SuSE Linux 8.0 / Turbo Linux2006年4月41共享存储编程一些细节(可先不关心)zC:y#pragma omp parallel clause clause . new-linestructured-blockzFortran:y!$OMP PARALLEL clause, clause.blocky!$OMP END PARALLELz子句子句clause是下列之一是下列之一:yif(expr):根据根据expr表达式执行结果决定是否并行执行表达式执行结果决定是否并行执行yprivate(lis

41、t):变量私有化变量私有化,默认为全部变量默认为全部变量yfirstprivate(list):在并行在并行区间之外引用区间之外引用变量首次赋值结果变量首次赋值结果ydefault(shared | none)(C)yDEFAULT(PRIVATE | SHARED | NONE)(Fortran)yshared(list):并行区间中的共享变量列表并行区间中的共享变量列表ycopyin(list):拷贝主线程的拷贝主线程的threadprivate公共区数据公共区数据yreduction(operator: list):归约操作归约操作2006年4月42共享存储编程OpenMP结构化块类型z

42、OpenMP主要有五类结构化块:y并行区Parallel Regionsy任务分割WorksharingxDO(Fortran)/for(C)结构:针对循环的并行化结构xSections:代码段间的并行xSingle:强制并行区中某些代码以串行方式执行(如:I/O)y数据环境Data Environmenty同步同步Synchronizationy运行时函数运行时函数/环境变量OpenMP最重要部分最重要部分2006年4月43共享存储编程循环分割:DO(Fortran)/for(C)结构zFortrany!$OMP DO clause, clause.ydo_loopy!$OMP END DO

43、 NOWAIT(可选)zC/C+y#pragma omp for clause clause . new-lineyfor-loopC$OMP PARALLELC$OMP DODO i=0,n #pragma omp parallel#pragma omp forfor (i=0;in;i+) 在在DO/for结构之后有一隐式结构之后有一隐式barrier同步操作同步操作,用用NO WAIT/no wait可以禁止可以禁止.2006年4月44共享存储编程比较parrallel构造与for构造for(i=0;IN;i+) ai = ai + bi;#pragma omp parallel int

44、 id, i, Nthrds, istart, iend; id = omp_get_thread_num(); Nthrds = omp_get_num_threads(); istart = id * N / Nthrds; iend = (id+1) * N / Nthrds; for(i=istart;Iiend;i+) ai = ai + bi;#pragma omp parallel#pragma omp for schedule(static)for(i=0;IN;i+) ai = ai + bi;串行代码用并行区实现并行化用任务分割构造实现并行化对于DO结构与PARALLEL结

45、构的比较同理,且以后讨论若无特别说明均基于C描述.2006年4月45共享存储编程并行区与任务分割间的关系z并行区和任务分割是OpenMP两类基本的并行性构造;z并行区中的代码对组内的各线程是可见的,也即并行区内的代码由各线程同时执行;z任务分割与并行区不同,它是将一个整体任务按负载平衡的方式分配给各线程来互相配合完成.z并行区是并行的先决条件,任务分割必须要与并行区一起使用才能生效;z并行区构造为!omp parallel;z任务分割构造有:do/for,section,和single三种.根进程并行区2006年4月46共享存储编程更详细的for语法z#pragma omp for claus

46、e clause . new-lineyfor-loopzClause可是下列说明可是下列说明:yprivate(list)yfirstprivate(list)ylastprivate(list)yreduction(operator: list)yorderedyschedule(kind, chunk_size)ynowait后面将详细后面将详细说明说明2006年4月47共享存储编程更详细的DO语法z!$OMP DO clause, clause.zdo_loopz!$OMP END DO NOWAITyPRIVATE(list)yFIRSTPRIVATE(list)yLASTPRIVA

47、TE(list)yREDUCTION(operator|intrinsic_procedure_name:list)ySCHEDULE(type,chunk)yORDERED2006年4月48共享存储编程DO/for使用注意事项z循环体必须紧接在DO或for之后.zFor循环必须为一结构化块,且其执行不被break语句中断.z在Fortran中,如果写上END DO制导语句,其必须要紧跟在DO循环的结束之后.z循环变量必须为整形.zSchedule, ordered,nowait子句只能出现一次.2006年4月49共享存储编程schedulezSchedule子名决定循环如何在各线程中进行分配

48、子名决定循环如何在各线程中进行分配:zschedule(dynamic,chunk)y各线程每次得到chunk_size大小的任务,执行完后继续取得任务,以此反复,直至任务完成(最后一任务可能会小于chunk_size).(任务池)y当chunk_size未被指定时,默认为1.zschedule(static,chunk)y如果chunk_size被指定, 则各线程按线程号顺序每人每得chunk次的循环任务,如果任务不能一次平分掉,则分配循环进行.y如果chunk_size未被指定,则各线程任务数即为循环数除以所用线程数的结果.zschedule(guided,chunk)y开始以一大的单位进

49、行分配忆,逐渐减小到chunk指定的值.zschedule(runtime)y分配方式与chunk值大小取决于环境变量OMP_SCHEDULE的设置.zchunk以循环次数为单位.z示意图见下页.2006年4月50共享存储编程Schedule示意图Work poolWork.Dynamic方式Static方式执行时间Guided方式Work.2006年4月51共享存储编程适用条件z静态:适用于大部分情形.y特点:x各线程任务明确,在任务分配时无需同步操作.x运行快的线程需等慢的线程为:z动态:适用于任务数量可变或不确定的情形(如条件收敛循环).y特点:x各线程将要执行的任务不可预见,任务分配需

50、同步操作.zGuided:线程异步到达for结构y特点:x首先到达的线程总是分得q=ceiling(n/p)次循环,然后n=max(n-q,p*k),循环分配,直到n=p*k为止.z环境变量:无需重新编译程序,可根据原始输入数据的情况改变任务分配策略.2006年4月52共享存储编程NOWAIT子句(Fortran)C$OMP PARALLEL C$OMP DO do i=1,n a(i)= cos(a(i) enddoC$OMP END DOC$OMP DO do i=1,n b(i)=a(i)+b(i) enddoC$OMP END DOC$OMP END PARALLELC$OMP PAR

51、ALLEL C$OMP DO do i=1,n a(i)= cos(a(i) enddoC$OMP END DO NOWAITC$OMP DO do i=1,n b(i)=a(i)+b(i) enddoC$OMP END DOC$OMP END PARALLEL隐式隐式BARRIERNo BARRIER默认循环变量默认循环变量i为私有线程私有类型变量为私有线程私有类型变量END DO必须紧随enddo,可省略.2006年4月53共享存储编程no wait子句(C)#pragma omp parallel #pragma omp for for(i=1;in;i+) a(i)= cos(a(i)

52、; #pragma omp for for(i=1;in;i+) b(i)=a(i)+b(i); 为并行区.隐式隐式BARRIER#pragma omp parallel #pragma omp for no wait for(i=1;in;i+) a(i)= cos(a(i); #pragma omp for no wait for(i=1;in;i+) b(i)=a(i)+b(i); No BARRIER2006年4月54共享存储编程Sections构造(非循环并行)zSections用于程序中大范围的非迭代执行代码段间的并行化.(如前10行和后10行间代码间无依赖关系,可以并行.)缺省时

53、每一个缺省时每一个“omp sections”构造结束后有一个构造结束后有一个barrier同步操作同步操作.通过通过使用使用 “nowait” 子句禁止隐式子句禁止隐式barrier同步同步(在构造语句后直接加即可在构造语句后直接加即可).与与for结构相类似结构相类似,OpenMP也提供也提供parallel sections.#pragma omp sections no waitx_calculation();#pragma omp sectiony_calculation();#pragma omp sectionz_calculation();x_calculation(),y_c

54、alculation()以及z_calculation()代表三部分之间无依赖关系 的非循环代码段.实质上它们各代表很多行代码.2006年4月55共享存储编程SinglezSingle:强制并行区中某些代码以串行方式执行强制并行区中某些代码以串行方式执行y#pragma omp single clause clause . new-linexstructured-blockyClause is one of the following:xprivate(list)xfirstprivate(list)xnowait2006年4月56共享存储编程Work sharing语句汇总zFortrany

55、DOySECTIONSySINGLEyWORKSHAREzCyforysectionsysingle2006年4月57共享存储编程Binding并行结构的联合使用并行结构的联合使用#pragma omp parallel forfor (I=0;IN;I+)NEAT_STUFF(I);#pragma omp parallel#pragma omp forfor (I=0;IN;I+)NEAT_STUFF(I);=for, sections, single, master, and barrier如果不位于并行区内或不与并行区联合使用,便不起任何作用. 2006年4月58共享存储编程Fortra

56、n!$OMP PARALLEL SECTIONS clause, clause.!$OMP SECTION block!$OMP SECTIONblock. . .!$OMP END PARALLEL SECTIONS!$OMP PARALLEL DO clause, clause.do_loop!$OMP END PARALLEL DO!$OMP PARALLEL WORKSHARE clause, clause.block!$OMP END PARALLEL WORKSHARE2006年4月59共享存储编程C#pragma omp parallel for clause clause .

57、new-linefor-loop#pragma omp parallel sections clause clause . new-line#pragma omp section new-linestructured-block#pragma omp section new-linestructured-block.2006年4月60共享存储编程OpenMP结构化块类型zOpenMP主要有五类结构化块:y并行区Parallel Regionsy任务分割Worksharingy数据环境Data Environmenty同步同步Synchronizationy运行时函数运行时函数/环境变量2006

58、年4月61共享存储编程默认数据类型z共享变量编程模型共享变量编程模型:y 大部分变量默认为共享类型大部分变量默认为共享类型z各线程共享全局变量各线程共享全局变量y Fortran: COMMON 块块, SAVE 变量变量, MODULE 变量变量y C: File scope variables, staticz但并不是所有变量全部共享但并不是所有变量全部共享.y 在并行区内调用的子程序中的栈变量是私有在并行区内调用的子程序中的栈变量是私有y 在语句块中的在语句块中的Auto变量为私有变量变量为私有变量.2006年4月62共享存储编程举例说明变量类型subroutine workcommon

59、 /input/ A(10)real temp(10)integer countsave countprogram sortcommon /input/ A(10)integer index(10)call inputC$OMP PARALLELcall work(index)C$OMP END PARALLELprint*, index(1)变量A,index和cound为所有线程共享.temp为线程私有变量,各线程间到不可见.2006年4月63共享存储编程变量类型改变z变量类型编译制导变量类型编译制导: threadprivate:将某些全局变量或数据区变为线程私有.z通过下列类型属性子句

60、来改变变量类型:y shared(并行区结构)y privatey firstprivatey lastprivate:循环体内的私有变量可以转变为全局变量循环体内的私有变量可以转变为全局变量, 在循在循环结束后访问环结束后访问;z默认数据类型状态可以改变默认数据类型状态可以改变:y default (private | shared | none)2006年4月64共享存储编程私有类型变量z变量私有化是OpenMP采用的重要的编译技术.y变量私有化;y私有变量初始化:xCopyinxFirstprivatey私有变量返回:xReductionxLastprivatezOpenMP私有类型变量

61、是指并行区内的只能被线程组内的某一线程访问的变量.zOpenMP的私有变量包括:y并行区内定义的变量;y由threadprivate 制导语句指明的变量;y由private, firstprivate,lastprivate, or reduction 子句指定的变量;y循环控制变量.2006年4月65共享存储编程Threadprivate:线程的全局私有变量 parameter (N=1000) real A(N,N)C$OMP THREADPRIVATE(/buf/) common/buf/lft(N),rht(N)C$OMP PARALLEL call init call scale c

62、all orderC$OMP END PARALLEL subroutine scale parameter (N=1000)C$OMP THREADPRIVATE(/buf/) common/buf/lft(N),rht(N) do i=1, N lft(i)= const* A(i,iam) end do return end subroutine order parameter (N=1000)C$OMP THREADPRIVATE(/buf/) common/buf/lft(N),rht(N) do i=1, N A(i,iam) = lft(index) end do return

63、endbuf 是线程内的公共块2006年4月66共享存储编程Privatezprivate(list)表明list中所列变量为组内线程私有变量.y 对变量不进行初始化对变量不进行初始化(有构造函数除外有构造函数除外)y 私有拷贝独立存储私有拷贝独立存储,不与原变量一致不与原变量一致main() int i = 10000; #pragma omp parallel private(i) i = -10000; printf(%dn,i);运行:10000main() int i = 10000; #pragma omp parallel i = -10000; printf(%dn,i);运行

64、:-100002006年4月67共享存储编程zPrivate变量将在组内每一线程中进行创建创建,如果只有如果变量有构造函数,则调用构造函数进行初始化,否则该私有变量的值不确定.z在进入并行结构中,私有变量引用的原变量值是不确定的;也不能在并行构造对引用的变量进行修改,在结构中对这些对私有变量的修改不影响退出结构后的同名变量值.z私有变量应在并行性构造中进行初始化;z私有变量不能为引用类型(破坏了数据的独立性);2006年4月68共享存储编程?For结构中:main() int i,sum=0,myid; #pragma omp parallel for private(i,sum) for(i

65、=0;i10;i+) myid = omp_get_thread_num(); printf(%dn,myid); sum = sum + 1; printf(%dn,sum); printf(sum = %dn,sum);3804398705280439870528043987062804398707080439870508043987060804398707180439870518043987061804398707sum = 10变量sum未初始化.2006年4月69共享存储编程FirstprivatezFirstprivate是 private的特殊情况.y 在主线程中初始化每一个线程

66、的私有拷贝变量在主线程中初始化每一个线程的私有拷贝变量.main() int i,sum=0,myid; #pragma omp parallel for firstprivate(i,sum) for(i=0;i10;i+)sum = sum + 1; printf(%dn,sum); printf(sum = %dn,sum);1231123123:2006年4月70共享存储编程LastprivatezLastprivate将位于迭代末的私有变量转化为全局变量.#pragma omp parallel #pragma omp for lastprivate(i) for (i=0; in-

67、1; i+) ai = bi + bi+1;ai=b0;for (i=1;in-1;i+)a(i)= b(i+1)a(i) = b(0)顺序执行顺序执行i=n-12006年4月71共享存储编程z默认情形=default(shared)(因此不显示使用)z改变默认default(private):y将并行区内变量的默认类型改为私有,而不是共享y省去在每一并行区结构后加private(list) zdefault(none): 指事先指定并行区中变量的默认类型zFortran支持default(private).zC/C+ 无default(private),只有default(shared) 和

68、default(none).Default2006年4月72共享存储编程DEFAULT例(Fortran)itotal = 1000C$OMP PARALLEL DEFAULT(PRIVATE) SHARED(itotal)np = omp_get_num_threads()each = itotal/npC$OMP END PARALLELitotal = 1000C$OMP PARALLEL PRIVATE(np, each)np = omp_get_num_threads()each = itotal/npC$OMP END PARALLEL2006年4月73共享存储编程reductio

69、nz归约操作(将各线程中处理结果经某种运算后送回到根进程)y reduction (op : list).yList中所列变量必须为并行区内的共享变量.z支持的运算操作:yOperator Initializationy+ 0y* 1y& 1y| 0z仅支持标量的归约操作#pragma omp parallel for private(i) shared(x, y, n) reduction(+: a, b)for (i=0; in; i+) a = a + xi;b = b + yi;2006年4月74共享存储编程实例:PI求解z通过数值积分的方法串行求解PI很简单的(具体代码见下一页).z

70、基于OpenMP将该串行程序并行化.依据使用制导语句的不同,可有若干种方法(我们只讨论基于刚讲过的并行区与for结构):y仅用并行区结构将该程序改为一SPMD并行程序.y用任务分割结构进行并行化用任务分割结构进行并行化.z归约.2006年4月75共享存储编程串行程序#include stdio.hmain(int argc,char* argv) n = atoi(argv1); w = 1.0 / (double) n; sum = 0.0; for(i=0;in;i+) x = w * (double)i - 0.5); sum = sum + 4.0/(1.0+x*x); pi = w

71、* sum; printf(Computed pi = %.16fn,pi); 2006年4月76共享存储编程仅基于Parallel块结构的并行程序 #include stdio.h main(int argc, char *argv) n = atoi(argv1); w = 1.0 / (double) n; sum = 0.0; #pragma omp parallel private(x) shared(w) reduction(+:sum) myid = omp_get_thread_num(); numthreads = omp_get_num_threads(); for(i=m

72、yid;in;i+=numthreads) x = w * (double)i - 0.5); sum = sum + 4.0/(1.0+x*x); . 类似于多线程编程2006年4月77共享存储编程基于for结构的并行化代码 #include stdio.h main(int argc, char *argv) n = atoi(argv1); w = 1.0 / (double) n; sum = 0.0; #pragma omp for reduction(+:sum) for(i=0;in;i+) x = w * (double)i - 0.5); sum = sum + 4.0/(1

73、.0+x*x); pi = w * sum; printf(Computed pi = %.16fn,pi); 与Pthreads比较2006年4月78共享存储编程OpenMP结构化块类型zOpenMP主要有五类结构化块:y并行区Parallel Regionsy任务分割Worksharingy数据环境Data Environmenty同步同步Synchronizationy运行时函数运行时函数/环境变量2006年4月79共享存储编程OpenMP同步z共享变量读写z单一文件I/OzOpenMP提共下列同步结构:y atomicy critical sectiony barriery flush

74、y orderedy singley master这两个结构实质上不属于同步结构,是并行区结构和任务分割结构中的内容.2006年4月80共享存储编程critical sectionz同时至多有一个线程进入临界区.z#pragma omp critical (name) new-line structured-blockC$OMP PARALLEL DO PRIVATE(B)C$OMP& SHARED(RES)DO 100 I=1,NITERSB = DOIT(I)C$OMP CRITICALCALL CONSUME (B, RES)C$OMP END CRITICAL100 CONTINUE2

75、006年4月81共享存储编程atomiczAtomic是临界区的特例,主要用于某些简单的语句.y#pragma omp atomic new-line expression-stmty其中expression-stmt只能为下列情形:xx binop = expr (bino只能是+ * - / & | ) xx+x+xxx-x-xz仅用于内存变量的更新仅用于内存变量的更新(在下面的例子中即对X的更新)C$OMP PARALLEL PRIVATE(B)B = DOIT(I)C$OMP ATOMICX = X + BC$OMP END PARALLEL2006年4月82共享存储编程z下面两段代码

76、区别是什么?#pragma omp parallel for shared(x, y, index, n)for (i=0; in; i+) #pragma omp atomicxindexi += work1(i);yi += work2(i);#pragma omp parallel for shared(x, y, index, n)for (i=0; in; i+) #pragma omp criticalxindexi += work1(i);yi += work2(i);原子操作临界区2006年4月83共享存储编程原子操作和临界区比较 z原子性是指操作的不可再分性原子性是指操作的不

77、可再分性,OpenMP利用原子结构主要利用原子结构主要是用于防止多线程对内存的同一地址的并发写是用于防止多线程对内存的同一地址的并发写.z临界区可以完成所有的原子操作临界区可以完成所有的原子操作.z原子结构可更好被编译优化原子结构可更好被编译优化:y有硬件指令可用于实现原子操作有硬件指令可用于实现原子操作,而且系统开销也很小而且系统开销也很小.z原子操作与并发并不矛盾原子操作与并发并不矛盾,z临界区一定是串行执行的,原子操作不一定是串行执行临界区一定是串行执行的,原子操作不一定是串行执行2006年4月84共享存储编程barrierzBarrier: 每一线程等待直至所有组内其它线程执行到每一线

78、程等待直至所有组内其它线程执行到Barrier为止为止.#pragma omp parallel shared (A, B, C) private(id)id=omp_get_thread_num();Aid = big_calc1(id);#pragma omp barrier#pragma omp forfor(i=0;iN;i+)Ci=big_calc3(I,A);#pragma omp for nowaitfor(i=0;iN;i+)Bi=big_calc2(C, i);Aid = big_calc3(id);for结构有隐式barrier同步for结构无隐式barrier同步para

79、llel结构隐式barrier同步2006年4月85共享存储编程zOrdered用于指定循环中各线程执行任务的顺序严格与顺序方式时的执行顺序一致.z以制导语句,而不是子句出现的ordered,只能出现在并行区动态范围内z如:在并行区中按顺序方式打印输出:orderedvoid worker(int k) #pragma omp ordered printf(“%d ”,k);main()int i;#pragma omp parallel for schedule(dynamic)for(i=0;i5;i+)worker(i);运行结果运行结果:0 1 2 3 42006年4月86共享存储编程

80、masterzMaster结构用于标志一个结构块只能由主线程执行. 其它线程跨越该块.该结构无隐式barrier同步.#pragma omp parallel private (tmp)do_many_things();#pragma omp master exchange_boundaries(); #pragma barrierdo_many_other_things();2006年4月87共享存储编程singlezSingle结构用于标志一个块内的代码仅能由一个线程执行(不一定是主线程).z在在single块后有一隐式的barrier同步操作.#pragma omp parallel#p

81、ragma omp singleprintf(Beginning work1.n);work1();#pragma omp singleprintf(Finishing work1.n);#pragma omp single nowaitprintf(Finished work1 and beginning work2.n);work2();最早遇到single块者执行同步同步不同步2006年4月88共享存储编程flushz#pragma omp flush (list) new-linez!$OMP FLUSH (list)zFlush语句可显式或隐式执行.用于在程序的某一点处,确定共享内存

82、中的变量对各线程的应印象是一致的.y如:编译器必须将寄存器中的值写回内存,硬件刷新缓冲区等.2006年4月89共享存储编程Flush(Fortran)z隐式flushyBARRIERyCRITICAL and END CRITICALyEND DOyEND SECTIONSyEND SINGLEyEND WORKSHAREyORDERED and END ORDEREDyPARALLEL and END PARALLELyPARALLEL DO and END PARALLEL DOyPARALLEL SECTIONS and END PARALLEL SECTIONSyPARALLEL WO

83、RKSHARE and END PARALLEL WORKSHAREz下列语句无隐式flushyDOyMASTER and END MASTERySECTIONSySINGLEyWORKSHARE2006年4月90共享存储编程Flush(C)z隐式flushybarrieryCritical区的出入口yOrdered区的出入口yParallel的出口yFor的出口ySections的出口ySingle的出口z无隐式flushyno wait2006年4月91共享存储编程隐式同步z下列OpenMP结构之后有隐式Barrier:end parallelend do (用用nowait禁止禁止)en

84、d sections (用用nowait禁止禁止)end criticalend single (用用nowait禁止禁止)2006年4月92共享存储编程Nesting并行结构的嵌套并行结构的嵌套z一个parallel语句可以出现在嵌套在另一个parallel内.如果不明确指定嵌套并行性,则该并行区的线程组只由当前的线程组成,否则,该并行区可建立自己的线程组.z同一parallel内的for, sections, 和 single语句不允许相互嵌套. z同名critical语句不允许相互嵌套.zfor, sections, 和 single 不能出现在critical, ordered, 和

85、master 的动态范围中.zbarrier 语句不能出现在 for, ordered, sections, single, master, 和 critical 的动态范围中.zmaster 不能出现在 for, sections, 和 single 的动态范围内.zordered 不能出现在 critical的动态范围内.2006年4月93共享存储编程OpenMP结构化块类型zOpenMP主要有五类结构化块:y并行区Parallel Regionsy任务分割Worksharingy数据环境Data Environmenty同步同步Synchronizationy运行时函数运行时函数/环境变

86、量2006年4月94共享存储编程OpenMP函数z锁函数yomp_init_lock(), omp_set_lock(), omp_unset_lock(), omp_test_lock(), omp_destroy_lock()z运行时环境函数:y 改变或检查线程数yomp_set_num_threads(), omp_get_num_threads(), omp_get_thread_num(), omp_get_max_threads()y 开/关嵌套和动态代码yomp_set_nested(), omp_set_dynamic(), omp_get_nested(), omp_get_

87、dynamic()y 当前代码位于并行区内吗?yomp_in_parallel()y 机器有多少个处理器?yomp_get_num_procs()2006年4月95共享存储编程例:锁的使用z下面的例子是用来显示锁的使用:y锁对象具有omp_lock_t,在锁使用前需对锁进行初始化: omp_init_lock().y当一个线程试图获得锁以进入第一个临界区时,处理于空闲状态,以等待进入临界区.y一旦得到锁,则对临界区加锁: omp_set_lock(),退出完临界区时解锁omp_unset_lock().y在进入第二个临界区时,则通过非阻塞函数omp_test_lock()来测试可能性,同时做一

88、些其它的事情.y在锁不再使用时,用omp_destroy_lock()销毁.2006年4月96共享存储编程#include int main()omp_lock_t lck;int id;omp_init_lock(&lck);#pragma omp parallel shared(lck) private(id)id = omp_get_thread_num();omp_set_lock(&lck);printf(My thread id is %d.n, id);omp_unset_lock(&lck);while (! omp_test_lock(&lck) skip(id); /* w

89、e do not yet have the lock, so we must do something else */work(id); /* we now have the lock and can do the work */omp_unset_lock(&lck);omp_destroy_lock(&lck);2006年4月97共享存储编程锁:保护共享资源omp_lock_t lck;omp_init_lock(&lck);#pragma omp parallel private (tmp)id = omp_get_thread_num();tmp = do_lots_of_work(i

90、d);omp_set_lock(&lck);printf(“%d %d”, id, tmp);omp_unset_lock(&lck);2006年4月98共享存储编程设定动态模式设定动态模式,由程序来指定线程数由程序来指定线程数(一般默认线程数与处理器个数相等一般默认线程数与处理器个数相等).#include void main() omp_set_dynamic(0);omp_set_num_threads(4);#pragma omp parallel int id=omp_get_thread_num();do_lots_of_stuff(id); 2006年4月99共享存储编程指定线程

91、数指定线程数omp_set_dynamic(0);omp_set_num_threads(16);#pragma omp parallel shared(x, npoints) private(iam, ipoints)if (omp_get_num_threads() != 16) abort();iam = omp_get_thread_num();ipoints = npoints/16;do_by_16(x, iam, ipoints);2006年4月100共享存储编程得到线程数int numthreads;numthreads = omp_get_num_threads();prin

92、tf(“%dn”,numthreads);#pragma omp parallel private(i)numthreads = omp_get_num_threads();printf(“%dn”,numthreads);运行运行:144442006年4月101共享存储编程环境变量z线程任务调度控制线程任务调度控制y OMP_SCHEDULE “SCHEDULE, CHUNK_SIZE”z设定缺省线程数设定缺省线程数y OMP_NUM_THREADS INT_LITERALz是否允许各并行区内线程是否允许各并行区内线程数目不相同(动态生成线程组)?y OMP_DYNAMIC TRUE | F

93、ALSEy动态模式动态模式 (默认默认):x并行区中的线程数动态确定并行区中的线程数动态确定,各并行区可具有不同的线程数各并行区可具有不同的线程数.x此时此时,线程数设置函数线程数设置函数omp_set_num_threads()只设定一上限只设定一上限,实实际中发生的线程数可能要比我们设置的数目少际中发生的线程数可能要比我们设置的数目少.y静态模式静态模式:x由程序员确定并行区中线程的数量由程序员确定并行区中线程的数量.z嵌套并行区是否建立新的线程组或它们是否要串行化嵌套并行区是否建立新的线程组或它们是否要串行化?(仅由线程组中的主线程执行,如I/O操作等)y OMP_NESTED TRUE

94、 | FALSE(默认为FALSE)2006年4月102共享存储编程汇总z并行区yparallel z任务分割yforysectionsySinglezparallel forzparallel sectionsz同步ymasterycriticalybarrieryatomicyflushyorderedz并行区yparallel z任务分割zDOzSECTIONSzSINGLEzWORKSHAREzPARALLEL DOzPARALLEL SECTIONSzPARALLEL WORKSHAREz同步zMASTERzCRITICALzBARRIERzATOMICzFLUSHzORDERED2

95、006年4月103共享存储编程运行环境函数汇总omp_set_num_threadsomp_get_num_threadsomp_get_max_threadsomp_get_thread_numomp_get_num_procsomp_in_parallelomp_set_dynamicomp_get_dynamicomp_set_nestedomp_get_nestedOMP_SET_NUM_THREADSOMP_GET_NUM_THREADSOMP_GET_MAX_THREADSOMP_GET_THREAD_NUMOMP_GET_NUM_PROCSOMP_IN_PARALLELOMP_S

96、ET_DYNAMICOMP_GET_DYNAMICOMP_SET_NESTEDOMP_GET_NESTEDOMP_GET_WTIME OMP_GET_WTICK2006年4月104共享存储编程锁函数汇总omp_init_lock omp_init_nest_lockomp_destroy_lockomp_destroy_nest_lockomp_set_lockomp_set_nest_lockomp_unset_lockomp_unset_nest_lockomp_test_lockomp_test_nest_lockOMP_INIT_LOCKOMP_INIT_NEST_LOCKOMP_DE

97、STROY_LOCKOMP_DESTROY_NEST_LOCKOMP_SET_LOCKOMP_SET_NEST_LOCKOMP_UNSET_LOCK OMP_UNSET_NEST_LOCKOMP_TEST_LOCK OMP_TEST_NEST_LOCK2006年4月105共享存储编程环境变量(C和Fortran一样)OMP_SCHEDULE OMP_NUM_THREADS OMP_DYNAMICOMP_NESTED2006年4月106共享存储编程OpenMP特点总结z支持C,C+和Fortranz共享存储并行机并行编程的主流平台,获得并行机厂商和用户的广泛支持z特别适合于串行程序的逐步并行化y如:先进行一些特别耗时的大循环的并行化,然后再逐步进行再大粒度的并行.zOrphan制导语句的支持,使得OpenMP较之于以前的共享存储编程模型更适合粗粒度的并行2006年4月107共享存储编程谢谢!2006年4月108共享存储编程

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 工作计划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号