版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、2006年4月,共享存儲(chǔ)編程,1/108,,機(jī)群應(yīng)用開發(fā)并行編程原理及程序設(shè)計(jì)Parallel Programming: Fundamentals and Implementation戴 榮dair@dawning.com.cn曙光信息產(chǎn)業(yè)有限公司2006.4,2006年4月,共享存儲(chǔ)編程,2/108,參考文獻(xiàn),黃鎧,徐志偉著,陸鑫達(dá)等譯. 可擴(kuò)展并行計(jì)算技術(shù),結(jié)構(gòu)與編程. 北京:機(jī)械工業(yè)出版社, P.33~56
2、,P.227~237, 2000.陳國良著.并行計(jì)算—結(jié)構(gòu)、算法、編程. 北京:高等教育出版社,1999.Barry Wilkinson and Michael Allen. Parallel Programming(Techniques and Applications using Networked Workstations and Parallel Computers). Prentice Hall, 1999.李曉梅,莫?jiǎng)t
3、堯等著. 可擴(kuò)展并行算法的設(shè)計(jì)與分析. 北京:國防工業(yè)出版社,2000.張寶琳,谷同祥等著. 數(shù)值并行計(jì)算原理與方法. 北京:國防工業(yè)出版社,1999.都志輝著. 高性能計(jì)算并行編程技術(shù)—MPI并行程序設(shè)計(jì). 北京:清華大學(xué)出版社, 2001.,2006年4月,共享存儲(chǔ)編程,3/108,相關(guān)網(wǎng)址,MPI: http://ww.mpi-forum.org, http://www.mcs.anl.gov/mpiPthreads
4、: http://www.oreilly.comPVM: http://www.epm.ornl.gov/pvm/ OpemMP: http://www.openmp.org網(wǎng)上搜索:www.google.com,2006年4月,共享存儲(chǔ)編程,4/108,共享存儲(chǔ)編程Programming with Shared Memory,2006年4月,共享存儲(chǔ)編程,5/108,共享存儲(chǔ)并行機(jī)模型,體系結(jié)構(gòu)特點(diǎn):多臺(tái)處理機(jī)通過互聯(lián)網(wǎng)絡(luò)共
5、享一個(gè)統(tǒng)一的內(nèi)存空間,通過單一內(nèi)存地址來實(shí)現(xiàn)處理機(jī)間的協(xié)調(diào).內(nèi)存空間也可由多個(gè)存儲(chǔ)器模塊構(gòu)成.每臺(tái)處理機(jī)可以執(zhí)行相同或不同的指令流,每臺(tái)處理機(jī)可以直接訪問到所有數(shù)據(jù).處理機(jī)間通信是借助于共享主存來實(shí)現(xiàn)的.可擴(kuò)展性差,當(dāng)處理機(jī)需要同時(shí)訪問共享全局變量時(shí),產(chǎn)生內(nèi)存競爭現(xiàn)象而嚴(yán)重影響效率,比較適合中小規(guī)模應(yīng)用問題的計(jì)算和事務(wù)處理.,2006年4月,共享存儲(chǔ)編程,6/108,共享存儲(chǔ)編程標(biāo)準(zhǔn)與特點(diǎn),共享存儲(chǔ)器編程標(biāo)準(zhǔn)Pthreads(
6、線程標(biāo)準(zhǔn)) X3H5(線程標(biāo)準(zhǔn))OpenMP(最常用的共享存儲(chǔ)并行編程方式,是我們討論的重點(diǎn).)共享存儲(chǔ)器編程特點(diǎn)顯式多線程庫調(diào)用.(Pthreads).編譯制導(dǎo)語句,OpenMP等.語言C,Fortran77,Fortran90/95,C++…,2006年4月,共享存儲(chǔ)編程,7/108,并行編程標(biāo)準(zhǔn),線程庫標(biāo)準(zhǔn)(Thread Library)– Win32 API.– POSIX threads線程模型.– X3H
7、5:概念性線程模型編譯制導(dǎo)(Compiler Directives)– OpenMP - portable shared memory parallelism.,,2006年4月,共享存儲(chǔ)編程,8/108,為什么流行多線程編程?,線程:在進(jìn)程的內(nèi)部執(zhí)行的指令序列.相對(duì)于進(jìn)程,線程開銷小:創(chuàng)建一個(gè)線程的時(shí)間大約是建立一個(gè)新進(jìn)程的1/30。如在Sun4/75工作上站上,創(chuàng)建一個(gè)非綁定線程約為52微秒,而fork()一次的時(shí)間為170
8、0微秒。線程同步時(shí)間約是進(jìn)程同步時(shí)間的1/3.線程與RPC相結(jié)合,發(fā)揮多處理機(jī)的處理能力;發(fā)揮多處理器的處理能力;開發(fā)程序的并發(fā)性,改善程序的結(jié)構(gòu).容易實(shí)現(xiàn)數(shù)據(jù)共享:由于線程共用內(nèi)存地址,因此可實(shí)現(xiàn)數(shù)據(jù)共享例:一高性能Web服務(wù)器可為每一打開鏈接的瀏覽器分配一個(gè)線程,所有線程即可共用同一cache來訪問網(wǎng)站的熱點(diǎn)話題統(tǒng)一的標(biāo)準(zhǔn):以前各開發(fā)商提供互不兼容的線程庫,結(jié)果導(dǎo)致多線程程序不能很好地移值。自1995年的POSIX線
9、程標(biāo)準(zhǔn)實(shí)施之后,極大地促進(jìn)多線程編程的統(tǒng)一。各系統(tǒng)都支持Pthreads,如Linux、SUN、IBM AIX等。,2006年4月,共享存儲(chǔ)編程,9/108,Pthreads線程模型,POSIX1003.4a小組研究多線程編程標(biāo)準(zhǔn). 當(dāng)標(biāo)準(zhǔn)完成后,大多數(shù)支持多線程的系統(tǒng)都支持POSIX接口.很好的改善了多線程編程的可移植性.IEEE Portable Operating System Interface, POSIX, 1003.1-
10、1995標(biāo)準(zhǔn):POSIX線程模型:pthreads.,2006年4月,共享存儲(chǔ)編程,10/108,線程管理(Pthread為例),創(chuàng)建:pthread_create終止:pthread_exit匯合:pthread_join分離:pthread_detach線程屬性初始化:pthread_attr_init唯一執(zhí)行:pthread_once,2006年4月,共享存儲(chǔ)編程,11/108,同步對(duì)象,在共享存儲(chǔ)多處理器并行機(jī)上,線程
11、通過全局變量通信,對(duì)于全局變量的操作必須進(jìn)行同步。pthread提供兩個(gè)線程同步原語 : 互斥和條件變量.,2006年4月,共享存儲(chǔ)編程,12/108,互斥鎖函數(shù),函數(shù) 操作Mutex_init() 初始化一個(gè)互斥鎖Mutext_lock() 阻塞式加鎖操作Mutex_trylock() 非阻塞式加鎖操作Mutex_unlock()
12、 解鎖Mutex_destroy() 解除互斥狀態(tài),2006年4月,共享存儲(chǔ)編程,13/108,條件變量的函數(shù),函數(shù) 操作pthread_cond_init() 初始化條件變量pthread_cond_wait() 阻塞直至條件為真pthread_cond_signal() 強(qiáng)制條件為真,解除等待條件的線程的阻塞pthrea
13、d_cond_timedwait()阻塞直到指定條件為真或timeoutpthread_cond_broadcast()解除所有等待條件的線程的阻塞pthread_cond _destroy() 銷毀條件變量,2006年4月,共享存儲(chǔ)編程,14/108,Hello World(1),#include #include "stdio.h"void *worker();main(){pthre
14、ad_t thread;pthread_create(&thread,NULL,worker,NULL);pthread_join(thread,NULL);}void *worker(){printf("Hello World!\n");},編譯命令gcc hello.c –lpthread運(yùn)行結(jié)果Hello World!,2006年4月,共享存儲(chǔ)編程,15/108,,pthread
15、_t 線程數(shù)據(jù)類型pthread_create(&thread,NULL,worker,NULL);函數(shù)pthread_create()用于創(chuàng)建一新的線程,新線程一旦建立便進(jìn)入運(yùn)行狀態(tài)參數(shù):線程指針或句柄線程屬性變量,屬性參數(shù):默認(rèn)為NULL. 屬性對(duì)象一旦建立可以用于創(chuàng)建多個(gè)具有共同屬性的線程,線程創(chuàng)建后,可刪除屬性對(duì)象.線程要執(zhí)行的函數(shù)傳入該執(zhí)行函數(shù)的一個(gè)參數(shù),無則NULL.可以是任意類型線程的終止線程函數(shù)
16、正常終止返回;自調(diào)用pthear_exit()函數(shù);線程被取消;線程接收到中止的信號(hào);當(dāng)主進(jìn)程執(zhí)行exit()后,進(jìn)程及其全部線程全部終止.,2006年4月,共享存儲(chǔ)編程,16/108,,pthread_join(pthread_t wait_for,void** status); 等待直到線程結(jié)束;執(zhí)行該函數(shù)的線程發(fā)生阻塞,直到由wait_for指定的線程終止; 等與被等的兩線程必須是同一進(jìn)程內(nèi)部的線程(而且不是分離線程
17、);返回值0成功返回ESRCH參數(shù)wait_for指定的線程不存在或是一分離線程;EINVAL線程參數(shù)無效;EDEADLK 等待自身結(jié)束.不能有兩個(gè)線程同時(shí)等待同一個(gè)線程的結(jié)束, 否則其中一個(gè)線程正常返回,另外一個(gè)返回ESRCH錯(cuò)誤.,2006年4月,共享存儲(chǔ)編程,17/108,Hello World(2),#include #include "stdio.h"#define numthrd
18、s 5pthread_t *tid;void *worker();main(){int i;tid = (pthread_t*) calloc(numthrds,sizeof(pthread_t));for(i=0;i<numthrds;i++) pthread_create(&tid[i],NULL,worker,NULL);for(i=0;i<numthrds;i++) pthread_jo
19、in(tid[i],NULL);}void *worker(){ int myid; myid = pthread_self() - tid[0]; printf("Hello World from thread %d!\n",myid); },Hello World from thread 0!Hello World from thread 1!Hello World from thread
20、2!Hello World from thread 3!Hello World from thread 4!,2006年4月,共享存儲(chǔ)編程,18/108,Hello World(3),#include #include "stdio.h"#define numthrds 5pthread_t *tid;pthread_mutex_t mutex;int sum=0;void *worker();ma
21、in(){int i;tid = (pthread_t*) calloc(numthrds,sizeof(pthread_t));pthread_mutex_init(&mutex,NULL);for(i=0;i<numthrds;i++) pthread_create(&tid[i],NULL,worker,NULL);for(i=0;i<numthrds;i++) pthread_jo
22、in(tid[i],NULL);printf(“The sum is %d\n",sum);},void *worker(){ int myid,num; myid = pthread_self() - tid[0]; printf("%d was added to the sum in thread %d\n",myid*10,myid); pthread_mutex_lock
23、(&mutex);sum += myid*10;pthread_mutex_unlock(&mutex);return;},2006年4月,共享存儲(chǔ)編程,19/108,運(yùn)行結(jié)果,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 ad
24、ded to the sum in thread 340 was added to the sum in thread 4The sum is 100,2006年4月,共享存儲(chǔ)編程,20/108,基于多線程編程的PI求解,2006年4月,共享存儲(chǔ)編程,21/108,,#include #include "stdio.h"pthread_mutex_t reduction_mutex;pthread_t *t
25、id;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(
26、) - tid[0]; /*integrate 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_
27、mutex); pi += mypi; pthread_mutex_unlock(&reduction_mutex); return(0);},2006年4月,共享存儲(chǔ)編程,22/108,void main(argc,argv)int argc;char* argv[];{ int i; /*check command line */ if(argc != 3) { printf(&qu
28、ot;Usage: %s Num_intervals Num_threads\n",argv[0]); exit(0); } /*get num intervals and num threads from command line*/ n = atoi(argv[1]); num_threads = atoi(argv[2]); w = 1.0 / (double)n; pi = 0.0;
29、 tid = (pthread_t*) calloc (num_threads,sizeof(pthread_t));,/*initilize lock*/if(pthread_mutex_init(&reduction_mutex,NULL)){ fprintf(stderr,"Cannot init lock\n"); exit(1);}/*create the threads*/
30、 for(i = 0; i<num_threads; i++){if(pthread_create(&tid[i],NULL,PIworker,NULL)){ fprintf(stderr,"Cannot create thread %d\n",i); exit(1); } } /*join threads*/ for(i = 0; i < num
31、_threads; i++) pthread_join(tid[i],NULL); printf("computed pi = %.16f\n",pi);},gcc hello.c –lpthread a.out 1000 5computed pi = 3.1415927369231271,轉(zhuǎn)去Openmp,2006年4月,共享存儲(chǔ)編程,23/108,多線程并行編程特點(diǎn),pthread_create
32、()創(chuàng)建一個(gè)新線程比重新啟動(dòng)一個(gè)線程花費(fèi)的時(shí)間少: 需要時(shí)創(chuàng)建+任務(wù)結(jié)束立刻殺掉 vs. 維護(hù)一大堆的空閑線程并且相互切換.在加鎖的前提下訪問共享資源不支持?jǐn)?shù)據(jù)并行,適合于任務(wù)級(jí)并行,即一個(gè)線程單獨(dú)執(zhí)行一個(gè)任務(wù);不支持增量并行化,對(duì)于一個(gè)串行程序,很難用Pthreads進(jìn)行并行化Pthreads主要是面向操作系統(tǒng), 而不是為高性能計(jì)算設(shè)計(jì)的,因此不是并行計(jì)算程序設(shè)計(jì)的主流平臺(tái)。但是“多線程并發(fā)執(zhí)行”這種思想?yún)s被廣泛地應(yīng)用于高性能
33、計(jì)算。這就是我們即將要講的共享存儲(chǔ)并行編程的另外一種被并行機(jī)制造商和廣用并行計(jì)算用戶廣泛接受的平臺(tái):OpenMP,2006年4月,共享存儲(chǔ)編程,24/108,并行編程標(biāo)準(zhǔn),線程庫標(biāo)準(zhǔn)(Thread Library)– Win32 API.– POSIX threads線程模型.– X3H5:概念性線程模型編譯制導(dǎo)(Compiler Directives)– OpenMP - portable shared memory par
34、allelism.,,,2006年4月,共享存儲(chǔ)編程,25/108,www.openmp.org,An Industry Standard API for Shared Memory ProgrammingAn API for Writing Multithreaded Applications一系列編譯制導(dǎo)語句和庫函數(shù)使得Fortran, C and C++的多線程編程更加容易,2006年4月,共享存儲(chǔ)編程,26/108,與X
35、3H5的關(guān)系,X3H5是ANSI/X3授權(quán)的小組委員會(huì),主要目的是在PCF(the Parallel Computing Forum)工作的基礎(chǔ)上,發(fā)展并行計(jì)算的一個(gè)ANSI標(biāo)準(zhǔn). PCF是一非正式的工業(yè)組織,雖在DO循環(huán)的并行化方法的標(biāo)準(zhǔn)化方面做一些工作,但在起草擬了一個(gè)標(biāo)準(zhǔn)后就草草收?qǐng)?OpenMP專門針對(duì)這類并行化問題,并完成了這項(xiàng)工作,同時(shí)得到工業(yè)界的廣泛支持.,2006年4月,共享存儲(chǔ)編程,27/108,ANSI X3H5共
36、享編程標(biāo)準(zhǔn),概念性的編程模型(ANSI標(biāo)準(zhǔn)(1993))沒有任何商品化的共享存儲(chǔ)器系統(tǒng)依附于X3H5,但X3H5的基本概念影響以后共享存儲(chǔ)器系統(tǒng)的并行編程.(一些基本概念在OpenMP均出現(xiàn)!)X3H5支持C,Fortran77以及Fortran90語言.X3H5規(guī)定的基本的并行結(jié)構(gòu)用于并行性表述:并行塊(分散任務(wù)Work Sharing)并行循環(huán)單進(jìn)程,parallel {…}end parallel,psec
37、tions {…}end psections,pdo{…}end pdo,psingle{…}end psingle,,,,,2006年4月,共享存儲(chǔ)編程,28/108,X3H5編程實(shí)例,program main !程序以順序模式執(zhí)行A!A只由基本線程執(zhí)行parallel!轉(zhuǎn)換成并行模式B!B為每個(gè)組員所復(fù)制psections!并行塊開始sectionC!一個(gè)組員執(zhí)行
38、CsectionD!另一個(gè)組員執(zhí)行Dend psections!等待C和D都結(jié)束psingle暫時(shí)轉(zhuǎn)換成順序模式E!E只能被一個(gè)組員執(zhí)行end psingle!轉(zhuǎn)回并行模式pdo I=1,6!并行do循環(huán)開始F(i)!各線程分擔(dān)循環(huán)任務(wù)end pdo no wait!無隱式路障同步G!更多的復(fù)制代碼end parallel!結(jié)束并行模式H!根進(jìn)程執(zhí)行H…!
39、更多的并行構(gòu)造end,線程,P,Q,R,,,,B,B,E,C,,F(1:2),F(3:4),F(5:6),G,G,G,,H,隱式barrier,隱式barrier,隱式barrier,無隱式barrier,隱式barrier,B,D,,,各線程以負(fù)載平衡方式分擔(dān)任務(wù)可能為:F(1:1),F(2:2),F(3:6)…,,,,,2006年4月,共享存儲(chǔ)編程,29/108,X3H5例程執(zhí)行過程描述,程序以順序方式啟動(dòng),此時(shí)只有一個(gè)初始化線
40、程,稱為基本線程或主線程.當(dāng)程序遇到parallel時(shí),通過派生多個(gè)子線程轉(zhuǎn)換為并行執(zhí)行模式(線程數(shù)隱式?jīng)Q定).基本線程與它的子線程形成一個(gè)組.所有組員并行處理后繼并行代碼,直至end parallel.然后程序轉(zhuǎn)為順序模式,只有基本線程繼續(xù)執(zhí)行.子線程遇到內(nèi)部并行或任務(wù)分擔(dān)構(gòu)造時(shí),可以繼續(xù)派生其子線程,從而成為一個(gè)新組的基本線程.線程間同步,通信與交互隱式路障:parallel, end parallel, end pdo或en
41、d psingle處隱式barrier.如果不需,則加no wait;各處理機(jī)通過全局變量通信,通過私有變量封裝數(shù)據(jù),,,,,fork,,,,,,,,,…...,barrier,…,,,,,順序執(zhí)行,順序執(zhí)行,并行執(zhí)行,2006年4月,共享存儲(chǔ)編程,30/108,OpenMP: 并行模型,Fork-Join 并行模式:主線程根據(jù)需要?jiǎng)?chuàng)建一組子線程進(jìn)行工作分擔(dān).可對(duì)串行程序進(jìn)行逐步并行化.,2006年4月,共享存儲(chǔ)編程,31/108
42、,如何應(yīng)用OpenMP?,OpenMP常用于循環(huán)并行化:– 找出最耗時(shí)的循環(huán).– 將循環(huán)由多線程完成.在串行程序上加上編譯制導(dǎo)語句,完成并行化,因此可先完成串行程序,然后再進(jìn)行OpenMP并行化.,void main(){ double Res[1000]; for(int i=0;i<1000;i++) { do_huge_comp(Res[i]); }},void main(){ doubl
43、e Res[1000]; #pragma omp parallel for for(int i=0;i<1000;i++) { do_huge_comp(Res[i]);},串行程序,并行程序,用OpenMP將該循環(huán)通過多線程進(jìn)行任務(wù)分割,,,2006年4月,共享存儲(chǔ)編程,32/108,線程間如何交互?,OpenMP 是基于共享內(nèi)存模型.線程通過共享變量通信.訪問共享變量會(huì)導(dǎo)致race condition (競
44、態(tài)狀態(tài))race condition:是一種狀態(tài),在這種狀態(tài)下兩個(gè)實(shí)體(例如兩個(gè)處理過程)對(duì)同一資源進(jìn)行競爭,而系統(tǒng)沒有一種機(jī)制來測定首先要執(zhí)行的是哪一個(gè)。因此,由于系統(tǒng)不能保證數(shù)據(jù)的正確處理,其結(jié)果是不可預(yù)測的。為了避免線程進(jìn)入競態(tài)狀態(tài):通過同步對(duì)象來保護(hù)數(shù)據(jù)沖突.,2006年4月,共享存儲(chǔ)編程,33/108,OpenMP術(shù)語,大多OpenMP構(gòu)造是制導(dǎo)語句或pragmas.C和C++的pragmas形式為:#pragma
45、omp construct [clause [clause]…]Fortran中,制導(dǎo)語句形式為以下幾種:C$OMP CONSTRUCT [clause [clause]…]!$OMP CONSTRUCT [clause [clause]…](自由書寫格式唯一)*$OMP CONSTRUCT [clause [clause]…]例:以下三種等價(jià)(第一行為列數(shù))C23456789!$OMP PARALLEL DO SHARE
46、D(A,B,C)C$OMP PARALLEL DOC$OMP+SHARED(A,B,C)C$OMP PARALLELDOSHARED(A,B,C)由于OpenMP構(gòu)造為注釋性語句,因此一個(gè)OpenMP程序在用不支持OpenMP的編譯器編譯后,仍為串行程序.,2006年4月,共享存儲(chǔ)編程,34/108,Structured blocks(結(jié)構(gòu)化塊),結(jié)構(gòu)化塊性質(zhì):僅在塊頂有一個(gè)入口和塊底有一個(gè)出口;塊功能可通過構(gòu)造的語法清晰地
47、識(shí)別;塊內(nèi)除Fortran中的STOP語句和c/c++中的exit()語句外,不能有其它分支.大多OpenMP構(gòu)造為結(jié)構(gòu)化塊.,C$OMP PARALLEL10 ……if(…) goto 10C$OMP END PARALLELprint *,id,C$OMP PARALLEL10 …30…if(…) goto 20go to 10C$OMPEND PARALLELif(…) goto 3
48、020print *, id,一個(gè)結(jié)構(gòu)化塊,一個(gè)非結(jié)構(gòu)化塊,2006年4月,共享存儲(chǔ)編程,35/108,OpenMP結(jié)構(gòu)化塊類型,OpenMP主要有五類結(jié)構(gòu)化塊:并行區(qū)Parallel Regions任務(wù)分割Worksharing數(shù)據(jù)環(huán)境Data Environment同步Synchronization運(yùn)行時(shí)函數(shù)/環(huán)境變量在Fortran,C/C++中,OpenMP基本上是一樣的.,,2006年4月,共享存儲(chǔ)編程,36/
49、108,Parallel Regions(并行區(qū)),并行區(qū)是OpenMP的基本構(gòu)造,并行區(qū)內(nèi)的代碼由各線程同時(shí)執(zhí)行.當(dāng)一個(gè)線程執(zhí)行“omp parallel”后,建立一組線程,該線程成為新建立的線程組的主線程.所有線程構(gòu)成一線程組,各線程以線程ID區(qū)分,主線程ID為0.線程組并行執(zhí)行并行區(qū)內(nèi)代碼.如:建立一個(gè)4線程的并行區(qū):,double A[1000];omp_set_num_threads(4);#pragma omp p
50、arallel{ int ID = omp_thread_num(); worker(ID,A);},每一線程以不同的線程ID和相同的參數(shù)A執(zhí)行并行區(qū)內(nèi)代碼的一拷貝.ID(=0,1,2,3).,2006年4月,共享存儲(chǔ)編程,37/108,并行區(qū)的Lecical / dynamic extent以及Orphaned 制所語句,bar.fsubroutine whoamiexternal omp_get_thread_
51、numinteger iam, omp_get_thread_numiam = omp_get_thread_num()C$OMP CRITICALprint*,’Hello from ‘, iamC$OMP END CRITICALreturnend,poo.fC$OMP PARALLELcall whoamiC$OMP END PARALLEL,,Static/lexical extent:在書寫上直接包含在并行
52、區(qū)內(nèi)的部分.,,,,+,Dynamic extent:包括并行區(qū)內(nèi)直接和間接(函數(shù)調(diào)用)包含的內(nèi)容,也被稱為region.,,,Orphan制導(dǎo)語句:落在子程序中的制導(dǎo)語句,方便于子程序的并行化,免去傳統(tǒng)的inline處理,,,2006年4月,共享存儲(chǔ)編程,38/108,并行區(qū)代碼流程,double A[1000];omp_set_num_threads(4);#pragma omp parallel{ int ID = om
53、p_thread_num(); worker(ID,A);},,,,,opm_set_num_threads(4),worker(2,A),worker(1,A),worker(3,A),Double A[1000],worker(0,A),所有線程在此處同步(如,隱式barrier同步),每一線程執(zhí)行相同代碼,不同數(shù)據(jù).,所以,并行區(qū)結(jié)構(gòu)也被稱為SPMD結(jié)構(gòu).,2006年4月,共享存儲(chǔ)編程,39/108,Hello World(
54、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&qu
55、ot;,myid,numthreads); }},2006年4月,共享存儲(chǔ)編程,40/108,Hello World(Fortran),PROGRAM HELLO integer myid,numthreads integer omp_get_num_threads,omp_get_thread_num!$omp parallel private(numthreads,myid) numthr
56、eads = omp_get_num_threads() myid = omp_get_thread_num() print *, 'Hello World from thread' ,myid,'of',numthreads!$omp end parallel stop end,2006年4月,共享存儲(chǔ)編程,41/108,Op
57、enMP并行程序編譯,支持編譯OpenMP的編譯器會(huì)提供編譯器命令選項(xiàng),以解釋OpenMP編譯制導(dǎo)語句.IBM AIX xlc編譯器,編譯器命令選項(xiàng)為-qsmpxlc file.c –qsmpxlf_r file.f -qsmp (xlf_r為IBM AIX4.3為支持多線程編程的編譯器)曙光3000:OS: AIX4.3 -qsmp AIX4.3支持 OpenMP編譯選項(xiàng)Intel C/C++編譯器icc, Intel
58、Fortran編譯器選項(xiàng)為-openmpicc file.c –openmpifc file.f –openmp曙光4000L:OS:Redhat Linux 8.0PGI C/C++編譯器icc, PGI Fortran編譯器選項(xiàng)為-mppgcc file.c –mppgf77 file.f –mppgf90 file.f –mp曙光4000A:OS:SuSE Linux 8.0 / Turbo Lin
59、ux,2006年4月,共享存儲(chǔ)編程,42/108,一些細(xì)節(jié)(可先不關(guān)心),C:#pragma omp parallel [clause[ clause] ...] new-linestructured-blockFortran:!$OMP PARALLEL [clause[[,] clause]...]block!$OMP END PARALLEL子句clause是下列之一:if(expr):根據(jù)expr表達(dá)式執(zhí)行結(jié)果決
60、定是否并行執(zhí)行private(list):變量私有化,默認(rèn)為全部變量firstprivate(list):在并行區(qū)間之外引用變量首次賦值結(jié)果default(shared | none)(C)DEFAULT(PRIVATE | SHARED | NONE)(Fortran)shared(list):并行區(qū)間中的共享變量列表copyin(list):拷貝主線程的threadprivate公共區(qū)數(shù)據(jù)reduction(opera
61、tor: list):歸約操作,2006年4月,共享存儲(chǔ)編程,43/108,OpenMP結(jié)構(gòu)化塊類型,OpenMP主要有五類結(jié)構(gòu)化塊:并行區(qū)Parallel Regions任務(wù)分割WorksharingDO(Fortran)/for(C)結(jié)構(gòu):針對(duì)循環(huán)的并行化結(jié)構(gòu)Sections:代碼段間的并行Single:強(qiáng)制并行區(qū)中某些代碼以串行方式執(zhí)行(如:I/O)數(shù)據(jù)環(huán)境Data Environment同步Synchronizat
62、ion運(yùn)行時(shí)函數(shù)/環(huán)境變量,,OpenMP最重要部分,2006年4月,共享存儲(chǔ)編程,44/108,循環(huán)分割:DO(Fortran)/for(C)結(jié)構(gòu),Fortran!$OMP DO [clause[[,] clause]...]do_loop[!$OMP END DO [NOWAIT]](可選)C/C++#pragma omp for [clause[ clause] ... ] new-linefor-loop,C$OM
63、P PARALLELC$OMP DODO i=0,n …},#pragma omp parallel#pragma omp forfor (i=0;i<n;i++){ …},在DO/for結(jié)構(gòu)之后有一隱式barrier同步操作,用NO WAIT/no wait可以禁止.,2006年4月,共享存儲(chǔ)編程,45/108,比較parrallel構(gòu)造與for構(gòu)造,for(i=0;I<N;i++) { a[i
64、] = a[i] + b[i];},#pragma omp parallel{ int 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=ist
65、art;I<iend;i++) { a[i] = a[i] + b[i];}},#pragma omp parallel#pragma omp for schedule(static)for(i=0;I<N;i++) { a[i] = a[i] + b[i];},串行代碼,用并行區(qū)實(shí)現(xiàn)并行化,用任務(wù)分割構(gòu)造實(shí)現(xiàn)并行化,對(duì)于DO結(jié)構(gòu)與PARALLEL結(jié)構(gòu)的比較同理,且以后討論若無特別說明均基于C描述.,2006年4月,共
66、享存儲(chǔ)編程,46/108,并行區(qū)與任務(wù)分割間的關(guān)系,并行區(qū)和任務(wù)分割是OpenMP兩類基本的并行性構(gòu)造;并行區(qū)中的代碼對(duì)組內(nèi)的各線程是可見的,也即并行區(qū)內(nèi)的代碼由各線程同時(shí)執(zhí)行;任務(wù)分割與并行區(qū)不同,它是將一個(gè)整體任務(wù)按負(fù)載平衡的方式分配給各線程來互相配合完成.并行區(qū)是并行的先決條件,任務(wù)分割必須要與并行區(qū)一起使用才能生效;并行區(qū)構(gòu)造為!omp parallel;任務(wù)分割構(gòu)造有:do/for,section,和single三種
67、.,2006年4月,共享存儲(chǔ)編程,47/108,更詳細(xì)的for語法,#pragma omp for [clause[ clause] ... ] new-linefor-loopClause可是下列說明:private(list)firstprivate(list)lastprivate(list)reduction(operator: list)orderedschedule(kind[, chunk_size])n
68、owait,后面將詳細(xì)說明,2006年4月,共享存儲(chǔ)編程,48/108,更詳細(xì)的DO語法,!$OMP DO [clause[[,] clause]...]do_loop[!$OMP END DO [NOWAIT]]PRIVATE(list)FIRSTPRIVATE(list)LASTPRIVATE(list)REDUCTION({operator|intrinsic_procedure_name}:list)SCHEDUL
69、E(type[,chunk])ORDERED,2006年4月,共享存儲(chǔ)編程,49/108,DO/for使用注意事項(xiàng),循環(huán)體必須緊接在DO或for之后.For循環(huán)必須為一結(jié)構(gòu)化塊,且其執(zhí)行不被break語句中斷.在Fortran中,如果寫上END DO制導(dǎo)語句,其必須要緊跟在DO循環(huán)的結(jié)束之后.循環(huán)變量必須為整形.Schedule, ordered,nowait子句只能出現(xiàn)一次.,2006年4月,共享存儲(chǔ)編程,50/108,sc
70、hedule,Schedule子名決定循環(huán)如何在各線程中進(jìn)行分配:schedule(dynamic[,chunk])各線程每次得到chunk_size大小的任務(wù),執(zhí)行完后繼續(xù)取得任務(wù),以此反復(fù),直至任務(wù)完成(最后一任務(wù)可能會(huì)小于chunk_size).(任務(wù)池)當(dāng)chunk_size未被指定時(shí),默認(rèn)為1.schedule(static[,chunk])如果chunk_size被指定, 則各線程按線程號(hào)順序每人每得chunk次的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 最簡單的c程序設(shè)計(jì)――順序程序設(shè)計(jì)
- 4最簡單的c程序設(shè)計(jì)順序程序設(shè)計(jì)1
- 實(shí)驗(yàn)項(xiàng)目實(shí)驗(yàn)一最簡單的c程序設(shè)計(jì)
- 簡單c語言程序的例子
- 最容易理解矩陣鍵盤c程序
- c++簡單程序設(shè)計(jì)
- 二級(jí)c語言歷年真題匯總__第3篇最簡單的c程序—順序程序設(shè)計(jì)3月7(有答案)
- 最“簡單”的道理
- 最快最簡單最直接的醒酒方法
- 最簡單的動(dòng)物畫
- c語言程序設(shè)計(jì)----簡單計(jì)算器
- 入黨動(dòng)機(jī)最簡單的回答
- 2021最簡單的聘用合同
- 一c++語言概述c++簡單程序設(shè)計(jì)
- 最簡單有效的放生儀軌
- 最簡單有效的炒股方法
- 最簡單的炒股賺錢方法
- 基于回卷恢復(fù)的MPI程序容錯(cuò).pdf
- 簡單的pwm程序
- c++簡單時(shí)區(qū)時(shí)間計(jì)算程序設(shè)計(jì)報(bào)告
評(píng)論
0/150
提交評(píng)論