




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、2006年4月共享存儲(chǔ)編程1/108機(jī)群應(yīng)用開(kāi)發(fā)2006.42006.42006年4月共享存儲(chǔ)編程2/108z 黃鎧,徐志偉著,陸鑫達(dá)等譯. 可擴(kuò)展并行計(jì)算技術(shù)可擴(kuò)展并行計(jì)算技術(shù),結(jié)構(gòu)與編程結(jié)構(gòu)與編程. 北京:機(jī)械工業(yè)出版社, p.3356,p.227237, 2000.z 陳國(guó)良著.并行計(jì)算并行計(jì)算結(jié)構(gòu)、算法、編程結(jié)構(gòu)、算法、編程. 北京:高等教育出版社,1999.z barry wilkinson and michael allen. parallel programming(techniques and applications using networked workstations
2、and parallel computers). prentice hall, 1999.z 李曉梅,莫?jiǎng)t堯等著. 可擴(kuò)展并行算法的設(shè)計(jì)與分析可擴(kuò)展并行算法的設(shè)計(jì)與分析. 北京:國(guó)防工業(yè)出版社,2000.z 張寶琳,谷同祥等著. 數(shù)值并行計(jì)算原理與方法數(shù)值并行計(jì)算原理與方法. 北京:國(guó)防工業(yè)出版社,1999.z 都志輝著. 高性能計(jì)算并行編程技術(shù)高性能計(jì)算并行編程技術(shù)mpi并行程序設(shè)計(jì)并行程序設(shè)計(jì). 北京:清華大學(xué)出版社, 2001. 2006年4月共享存儲(chǔ)編程3/108z mpi: , /mpiz pthr
3、eads: http:/z pvm: /pvm/ z opemmp: z 網(wǎng)上搜索:2006年4月共享存儲(chǔ)編程4/1082006年4月共享存儲(chǔ)編程5/108體系結(jié)構(gòu)特點(diǎn)體系結(jié)構(gòu)特點(diǎn):多臺(tái)處理機(jī)通過(guò)互聯(lián)網(wǎng)絡(luò)共享一個(gè)統(tǒng)一的內(nèi)存空間,通過(guò)單一內(nèi)存地址單一內(nèi)存地址來(lái)實(shí)現(xiàn)處理機(jī)間的協(xié)調(diào).內(nèi)存空間也可由多個(gè)存儲(chǔ)器模塊構(gòu)成.每臺(tái)處理機(jī)可以執(zhí)行相同或不同的指令流,每臺(tái)處理機(jī)可以直接訪問(wèn)到所有數(shù)據(jù).處理機(jī)間通信是借助于共享主存來(lái)通信是借助于共享主存來(lái)實(shí)現(xiàn)的實(shí)現(xiàn)的.可擴(kuò)展性差,當(dāng)處理機(jī)需要同時(shí)訪問(wèn)共享全局變量時(shí),產(chǎn)生內(nèi)存競(jìng)爭(zhēng)現(xiàn)象而
4、嚴(yán)重影響效率,比較適合中小規(guī)模應(yīng)用問(wèn)題的計(jì)算和事務(wù)處理.2006年4月共享存儲(chǔ)編程6/108z 共享存儲(chǔ)器編程標(biāo)準(zhǔn)ypthreads(線程標(biāo)準(zhǔn)) yx3h5(線程標(biāo)準(zhǔn))yopenmp(最常用的共享存儲(chǔ)并行編程方式,是我們討論的重點(diǎn).)z 共享存儲(chǔ)器編程特點(diǎn)y顯式多線程庫(kù)調(diào)用.(pthreads).y編譯制導(dǎo)語(yǔ)句,openmp等.z 語(yǔ)言yc,fortran77,fortran90/95,c+2006年4月共享存儲(chǔ)編程7/108z 線程庫(kù)線程庫(kù)標(biāo)準(zhǔn)標(biāo)準(zhǔn)(thread library)y win32 api.y posix threads線程模型線程模型.y x3h5:概念性線程模型z 編譯制導(dǎo)編
5、譯制導(dǎo)(compiler directives)y openmp - portable shared memory parallelism.2006年4月共享存儲(chǔ)編程8/108z 線程線程:在進(jìn)程的內(nèi)部執(zhí)行的指令序列.z 相對(duì)于進(jìn)程,線程開(kāi)銷小:y創(chuàng)建一個(gè)線程的時(shí)間大約是建立一個(gè)新進(jìn)程的1/30。如在sun4/75工作上站上,創(chuàng)建一個(gè)非綁定線程約為52微秒,而fork()一次的時(shí)間為1700微秒。y線程同步時(shí)間約是進(jìn)程同步時(shí)間的1/3.z 線程與rpc相結(jié)合,發(fā)揮多處理機(jī)的處理能力;z 發(fā)揮多處理器的處理能力;z 開(kāi)發(fā)程序的并發(fā)性,改善程序的結(jié)構(gòu).z 容易實(shí)現(xiàn)數(shù)據(jù)共享:由于線程共用內(nèi)存地址,因
6、此可實(shí)現(xiàn)數(shù)據(jù)共享y例:一高性能web服務(wù)器可為每一打開(kāi)鏈接的瀏覽器分配一個(gè)線程,所有線程即可共用同一cache來(lái)訪問(wèn)網(wǎng)站的熱點(diǎn)話題z 統(tǒng)一的標(biāo)準(zhǔn):y以前各開(kāi)發(fā)商提供互不兼容的線程庫(kù),結(jié)果導(dǎo)致多線程程序不能很好地移值。自1995年的posix線程標(biāo)準(zhǔn)實(shí)施之后,極大地促進(jìn)多線程編程的統(tǒng)一。各系統(tǒng)都支持pthreads,如linux、sun、ibm aix等。2006年4月共享存儲(chǔ)編程9/108z posix1003.4a小組研究多線程編程標(biāo)準(zhǔn). 當(dāng)標(biāo)準(zhǔn)完成后,大多數(shù)支持多線程的系統(tǒng)都支持posix接口.很好的改善了多線程編程的可移植性.z ieee portable operating syste
7、m interface, posix, 1003.1-1995標(biāo)準(zhǔn):posix線程模型:pthreads.2006年4月共享存儲(chǔ)編程10/108z 創(chuàng)建:pthread_createz 終止:pthread_exitz 匯合:pthread_joinz 分離:pthread_detachz 線程屬性初始化:pthread_attr_initz 唯一執(zhí)行:pthread_once2006年4月共享存儲(chǔ)編程11/108z 在共享存儲(chǔ)多處理器并行機(jī)上,線程通過(guò)全局變量通信,對(duì)于全局變量的操作必須進(jìn)行同步。z pthread提供兩個(gè)線程同步原語(yǔ) : 互斥和條件變量.2006年4月共享存儲(chǔ)編程12/10
8、8 函數(shù)函數(shù) 操作操作mutex_init() 初始化一個(gè)互斥鎖mutext_lock() 阻塞式加鎖操作mutex_trylock() 非阻塞式加鎖操作mutex_unlock() 解鎖mutex_destroy() 解除互斥狀態(tài)2006年4月共享存儲(chǔ)編程13/108 函數(shù)函數(shù) 操作操作pthread_cond_init() 初始化條件變量pthread_cond_wait() 阻塞直至條件為真pthread_cond_signal() 強(qiáng)制條件為真,解除等待條件的線程的阻塞pthread_cond_timedwait() 阻塞直到指定條件為真或timeoutpthread_cond_bro
9、adcast()解除所有等待條件的線程的阻塞pthread_cond _destroy() 銷毀條件變量 2006年4月共享存儲(chǔ)編程14/108#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);編譯命令編譯命令gccgcc hello.c hello.c lpthreadlpthread運(yùn)運(yùn)行行結(jié)結(jié)果果hel
10、lo world!hello world!2006年4月共享存儲(chǔ)編程15/108z pthread_t 線程數(shù)據(jù)類型z pthread_create(&thread,null,worker,null);y函數(shù)pthread_create()用于創(chuàng)建一新的線程,新線程一旦建立便進(jìn)入運(yùn)行狀態(tài)y參數(shù):x線程指針或句柄x線程屬性變量,屬性參數(shù):默認(rèn)為null. 屬性對(duì)象一旦建立可以用于創(chuàng)建多個(gè)具有共同屬性的線程,線程創(chuàng)建后,可刪除屬性對(duì)象.x線程要執(zhí)行的函數(shù)x傳入該執(zhí)行函數(shù)的一個(gè)參數(shù),無(wú)則null.可以是任意類型z 線程的終止y線程函數(shù)正常終止返回;y自調(diào)用pthear_exit()函數(shù);y線
11、程被取消;y線程接收到中止的信號(hào);y當(dāng)主進(jìn)程執(zhí)行exit()后,進(jìn)程及其全部線程全部終止.2006年4月共享存儲(chǔ)編程16/108z pthread_join(pthread_t wait_for,void* status); y等待直到線程結(jié)束;y執(zhí)行該函數(shù)的線程發(fā)生阻塞,直到由wait_for指定的線程終止; y等與被等的兩線程必須是同一進(jìn)程內(nèi)部的線程(而且不是分離線程);y返回值x0成功返回xesrch參數(shù)wait_for指定的線程不存在或是一分離線程;xeinval線程參數(shù)無(wú)效;xedeadlk 等待自身結(jié)束.y不能有兩個(gè)線程同時(shí)等待同一個(gè)線程的結(jié)束, 否則其中一個(gè)線程正常返回,另外一個(gè)
12、返回esrch錯(cuò)誤.2006年4月共享存儲(chǔ)編程17/108hello world(2)hello world(2)#include #include stdio.h#define numthrds 5pthread_t *tid;void *worker();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,
13、null);void *worker() int myid; myid = pthread_self() - tid0; printf(hello world from thread %d!n,myid); hello world from thread 0!hello world from thread 1!hello world from thread 2!hello world from thread 3!hello world from thread 4!2006年4月共享存儲(chǔ)編程18/108#include #include stdio.h#define numthrds 5pthr
14、ead_t *tid;pthread_mutex_t mutex;int sum=0;void *worker();main()int i;tid = (pthread_t*) calloc(numthrds,sizeof(pthread_t);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);vo
15、id *worker() int myid,num; myid = pthread_self() - tid0; printf(%d was added to the sum in thread %dn,myid*10,myid); pthread_mutex_lock(&mutex);sum += myid*10;pthread_mutex_unlock(&mutex);return;2006年4月共享存儲(chǔ)編程19/1080 was added to the sum in thread 010 was added to the sum in thread 120 was ad
16、ded 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月共享存儲(chǔ)編程20/1084d1102xx222006年4月共享存儲(chǔ)編程21/108#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.
17、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; /*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(&
18、;reduction_mutex); pi += mypi; pthread_mutex_unlock(&reduction_mutex); return(0);2006年4月共享存儲(chǔ)編程22/108void main(argc,argv)int argc;char* argv; int i; /*check command line */ if(argc != 3) printf(usage: %s num_intervals num_threadsn,argv0); exit(0); /*get num intervals and num threads from command
19、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 lock*/if(pthread_mutex_init(&reduction_mutex,null) fprintf(stderr,cannot init lockn); exit(1);/*create the threads*/ for(i = 0; inum_threads; i+)
20、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_join(tidi,null); printf(computed pi = %.16fn,pi);gcc hello.c lpthread a.out 1000 5computed pi = 3.1415927369231271轉(zhuǎn)去openmp2006年4月共享存儲(chǔ)編程23/108z p
21、thread_create()創(chuàng)建一個(gè)新線程比重新啟動(dòng)一個(gè)線程花費(fèi)的時(shí)間少: 需要時(shí)創(chuàng)建+任務(wù)結(jié)束立刻殺掉 vs. 維護(hù)一大堆的空閑線程并且相互切換.z 在加鎖的前提下訪問(wèn)共享資源z 不支持?jǐn)?shù)據(jù)并行不支持?jǐn)?shù)據(jù)并行,適合于任務(wù)級(jí)并行,即一個(gè)線程單獨(dú)執(zhí)行一個(gè)任務(wù);z 不支持增量并行化,對(duì)于一個(gè)串行程序,很難用pthreads進(jìn)行并行化z pthreads主要是面向操作系統(tǒng)主要是面向操作系統(tǒng), 而不是為高性能計(jì)算設(shè)計(jì)的而不是為高性能計(jì)算設(shè)計(jì)的,因此因此不是并行計(jì)算程序設(shè)計(jì)的主流平臺(tái)不是并行計(jì)算程序設(shè)計(jì)的主流平臺(tái)。但是但是“多線程并發(fā)執(zhí)行多線程并發(fā)執(zhí)行”這種這種思想?yún)s被廣泛地應(yīng)用于高性能計(jì)算思想?yún)s被廣
22、泛地應(yīng)用于高性能計(jì)算。這就是我們即將要講的共享存這就是我們即將要講的共享存儲(chǔ)并行編程的另外一種被并行機(jī)制造商和廣用并行計(jì)算用戶廣泛接儲(chǔ)并行編程的另外一種被并行機(jī)制造商和廣用并行計(jì)算用戶廣泛接受的平臺(tái)受的平臺(tái):openmp2006年4月共享存儲(chǔ)編程24/108z 線程庫(kù)線程庫(kù)標(biāo)準(zhǔn)標(biāo)準(zhǔn)(thread library)y win32 api.y posix threads線程模型線程模型.y x3h5:概念性線程模型概念性線程模型z 編譯制導(dǎo)編譯制導(dǎo)(compiler directives)y openmp - portable shared memory parallelism.2006年4月共享
23、存儲(chǔ)編程25/108an industry standard api for shared memory programmingan api for writing multithreaded applications一系列編譯制導(dǎo)語(yǔ)句和庫(kù)函數(shù)使得fortran, c and c+的多線程編程更加容易的多線程編程更加容易2006年4月共享存儲(chǔ)編程26/108z 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)化方面做一
24、些工作,但在起草擬了一個(gè)標(biāo)準(zhǔn)后就草草收?qǐng)?z openmp專門針對(duì)這類并行化問(wèn)題,并完成了這項(xiàng)工作,同時(shí)得到工業(yè)界的廣泛支持.2006年4月共享存儲(chǔ)編程27/108z 概念性的編程模型(ansi標(biāo)準(zhǔn)(1993)y沒(méi)有任何商品化的共享存儲(chǔ)器系統(tǒng)依附于x3h5,但x3h5的基本概念影響以后共享存儲(chǔ)器系統(tǒng)的并行編程.(一些基本概念在openmp均出現(xiàn)!)z x3h5支持c,fortran77以及fortran90語(yǔ)言.z x3h5規(guī)定的基本的并行結(jié)構(gòu)用于并行性表述:y并行塊(分散任務(wù)work sharing)y并行循環(huán)y單進(jìn)程parallel end parallelpsections end ps
25、ectionspdoend pdopsingleend psingle2006年4月共享存儲(chǔ)編程28/108program main !程序以順序模式執(zhí)行a!a只由基本線程執(zhí)行parallel!轉(zhuǎn)換成并行模式b!b為每個(gè)組員所復(fù)制psections!并行塊開(kāi)始sectionc!一個(gè)組員執(zhí)行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)開(kāi)始f(i)!各線程分擔(dān)循環(huán)任務(wù)end pdo no wait!無(wú)隱式路障同步g!更多的復(fù)制代碼end p
26、arallel!結(jié)束并行模式h!根進(jìn)程執(zhí)行h!更多的并行構(gòu)造zend線程pqrbbecf(1:2)f(3:4) f(5:6)gggh隱式barrier隱式barrier隱式barrier無(wú)隱式barrier隱式barrierbd各線程以負(fù)載平衡方式分擔(dān)任務(wù)可能為:f(1:1),f(2:2),f(3:6)2006年4月共享存儲(chǔ)編程29/108z 程序以順序方式啟動(dòng),此時(shí)只有一個(gè)初始化線程,稱為基本線程或主線程.當(dāng)程序遇到parallel時(shí),通過(guò)派生多個(gè)子線程轉(zhuǎn)換為并行執(zhí)行模式(線程數(shù)隱式?jīng)Q定).基本線程與它的子線程形成一個(gè)組.所有組員并行處理后繼并行代碼,直至end parallel.然后程序轉(zhuǎn)
27、為順序模式,只有基本線程繼續(xù)執(zhí)行.z 子線程遇到內(nèi)部并行或任務(wù)分擔(dān)構(gòu)造時(shí),可以繼續(xù)派生其子線程,從而成為一個(gè)新組的基本線程.z 線程間同步,通信與交互y隱式路障:parallel, end parallel, end pdo或end psingle處隱式barrier.如果不需,則加no wait;y各處理機(jī)通過(guò)全局變量通信,通過(guò)私有變量封裝數(shù)據(jù) fork. barrier順序執(zhí)行順序執(zhí)行并行執(zhí)行2006年4月共享存儲(chǔ)編程30/108openmp: 并行模型并行模型z fork-join 并行模式:y主線程根據(jù)需要?jiǎng)?chuàng)建一組子線程進(jìn)行工作分擔(dān).y可對(duì)串行程序進(jìn)行逐步并行化.主線程主線程并行執(zhí)行區(qū)
28、域并行執(zhí)行區(qū)域2006年4月共享存儲(chǔ)編程31/108z openmp常用于循環(huán)并行化常用于循環(huán)并行化:y 找出最耗時(shí)的循環(huán).y 將循環(huán)由多線程完成.y在串行程序上加上編譯制導(dǎo)語(yǔ)句在串行程序上加上編譯制導(dǎo)語(yǔ)句,完成并行化完成并行化,因此可先完成串行因此可先完成串行程序程序,然后再進(jìn)行然后再進(jìn)行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;
29、i+) do_huge_comp(resi);串行程序并行程序用用openmp將該循環(huán)通過(guò)多線程進(jìn)行任務(wù)分割將該循環(huán)通過(guò)多線程進(jìn)行任務(wù)分割2006年4月共享存儲(chǔ)編程32/108z openmp 是基于共享內(nèi)存模型.y線程通過(guò)共享變量通信.z 訪問(wèn)共享變量會(huì)導(dǎo)致race condition (競(jìng)態(tài)狀態(tài))yrace condition:是一種狀態(tài),在這種狀態(tài)下兩個(gè)實(shí)體(例如兩個(gè)處理過(guò)程)對(duì)同一資源進(jìn)行競(jìng)爭(zhēng),而系統(tǒng)沒(méi)有一種機(jī)制來(lái)測(cè)定首先要執(zhí)行的是哪一個(gè)。因此,由于系統(tǒng)不能保證數(shù)據(jù)的正確處理,其結(jié)果是不可預(yù)測(cè)的。z 為了避免線程進(jìn)入競(jìng)態(tài)狀態(tài):y通過(guò)同步對(duì)象來(lái)保護(hù)數(shù)據(jù)沖突.2006年4月共享存儲(chǔ)編程33
30、/108z 大多大多openmp構(gòu)造是制導(dǎo)語(yǔ)句或構(gòu)造是制導(dǎo)語(yǔ)句或pragmas.yc和和c+的的pragmas形式為形式為:x#pragma omp construct clause clauseyfortran中中,制導(dǎo)語(yǔ)句形式為以下幾種制導(dǎo)語(yǔ)句形式為以下幾種:xc$omp construct clause clausex!$omp construct clause clause(自由書(shū)寫格式唯一)x*$omp construct clause clausex例:以下三種等價(jià)(第一行為列數(shù))xc23456789x!$omp parallel do shared(a,b,c)xc$omp pa
31、rallel doxc$omp+shared(a,b,c)xc$omp paralleldoshared(a,b,c)z 由于由于openmp構(gòu)造為注釋性語(yǔ)句構(gòu)造為注釋性語(yǔ)句,因此一個(gè)因此一個(gè)openmp程序在用不支持程序在用不支持openmp的編譯器編譯后的編譯器編譯后,仍為串行程序仍為串行程序.2006年4月共享存儲(chǔ)編程34/108z 結(jié)構(gòu)化塊性質(zhì):y僅在塊頂有一個(gè)入口和塊底有一個(gè)出口;y塊功能可通過(guò)構(gòu)造的語(yǔ)法清晰地識(shí)別;y塊內(nèi)除fortran中的stop語(yǔ)句和c/c+中的exit()語(yǔ)句外,不能有其它分支.z 大多大多openmp構(gòu)造為構(gòu)造為結(jié)構(gòu)化塊.c$omp parallel10 i
32、f() goto 10c$omp end parallelprint *,idc$omp parallel10 30if() goto 20go to 10c$ompend parallelif() goto 3020print *, id一個(gè)結(jié)構(gòu)化塊一個(gè)非結(jié)構(gòu)化塊2006年4月共享存儲(chǔ)編程35/108z openmp主要有五類結(jié)構(gòu)化塊:y并行區(qū)parallel regionsy任務(wù)分割worksharingy數(shù)據(jù)環(huán)境data environmenty同步同步synchronizationy運(yùn)行時(shí)函數(shù)運(yùn)行時(shí)函數(shù)/環(huán)境變量z 在fortran,c/c+中,openmp基本上是一樣的.2006年4
33、月共享存儲(chǔ)編程36/108z 并行區(qū)是openmp的基本構(gòu)造,并行區(qū)內(nèi)的代碼由各線程同時(shí)執(zhí)行.z 當(dāng)一個(gè)線程執(zhí)行“omp parallel”后,建立一組線程,該線程成為新建立的線程組的主線程.所有線程構(gòu)成一線程組,各線程以線程id區(qū)分,主線程id為0.z 線程組并行執(zhí)行并行區(qū)內(nèi)代碼.z 如:建立一個(gè)4線程的并行區(qū):double a1000;omp_set_num_threads(4);#pragma omp parallel int id = omp_thread_num(); worker(id,a);每一線程以不同的線程id和相同的參數(shù)a執(zhí)行并行區(qū)內(nèi)代碼的一拷貝.id(=0,1,2,3).
34、2006年4月共享存儲(chǔ)編程37/108bar.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:在書(shū)寫上直接包含在并行區(qū)內(nèi)的部分.+dynamic extent:包括并行區(qū)內(nèi)直接
35、和間接(函數(shù)調(diào)用)包含的內(nèi)容,也被稱為region.orphan制導(dǎo)語(yǔ)句:落在子程序中的制導(dǎo)語(yǔ)句,方便于子程序的并行化,免去傳統(tǒng)的inline處理2006年4月共享存儲(chǔ)編程38/108double 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同步)每一線程執(zhí)行相同代
36、碼,不同數(shù)據(jù).所以,并行區(qū)結(jié)構(gòu)也被稱為spmd結(jié)構(gòu).2006年4月共享存儲(chǔ)編程39/108#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月共享存儲(chǔ)編程40/108 program hello integer myid,numthreads integer omp_ge
37、t_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月共享存儲(chǔ)編程41/108支持編譯openmp的編譯器會(huì)提供編譯器命令選項(xiàng),以解釋openmp編譯制導(dǎo)語(yǔ)句.ibm aix xlc編譯器,編譯器命令選項(xiàng)為-qs
38、mpxlc 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 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曙光4000
39、a:os:suse linux 8.0 / turbo linux2006年4月共享存儲(chǔ)編程42/108z c:y#pragma omp parallel clause clause . new-linestructured-blockz fortran:y!$omp parallel clause, clause.blocky!$omp end parallelz 子句子句clause是下列之一是下列之一:yif(expr):根據(jù)根據(jù)expr表達(dá)式執(zhí)行結(jié)果決定是否并行執(zhí)行表達(dá)式執(zhí)行結(jié)果決定是否并行執(zhí)行yprivate(list):變量私有化變量私有化,默認(rèn)為全部變量默認(rèn)為全部變量yfirst
40、private(list):在并行在并行區(qū)間之外引用區(qū)間之外引用變量首次賦值結(jié)果變量首次賦值結(jié)果ydefault(shared | none)(c)ydefault(private | shared | none)(fortran)yshared(list):并行區(qū)間中的共享變量列表并行區(qū)間中的共享變量列表ycopyin(list):拷貝主線程的拷貝主線程的threadprivate公共區(qū)數(shù)據(jù)公共區(qū)數(shù)據(jù)yreduction(operator: list):歸約操作歸約操作2006年4月共享存儲(chǔ)編程43/108z openmp主要有五類結(jié)構(gòu)化塊:y并行區(qū)parallel regionsy任務(wù)分割
41、worksharingxdo(fortran)/for(c)結(jié)構(gòu):針對(duì)循環(huán)的并行化結(jié)構(gòu)xsections:代碼段間的并行xsingle:強(qiáng)制并行區(qū)中某些代碼以串行方式執(zhí)行(如:i/o)y數(shù)據(jù)環(huán)境data environmenty同步同步synchronizationy運(yùn)行時(shí)函數(shù)運(yùn)行時(shí)函數(shù)/環(huán)境變量openmp最重要部分最重要部分2006年4月共享存儲(chǔ)編程44/108z fortrany!$omp do clause, clause.ydo_loopy!$omp end do nowait(可選)z c/c+y#pragma omp for clause clause . new-lineyfo
42、r-loopc$omp parallelc$omp dodo i=0,n #pragma omp parallel#pragma omp forfor (i=0;in;i+) 在在do/for結(jié)構(gòu)之后有一隱式結(jié)構(gòu)之后有一隱式barrier同步操作同步操作,用用no wait/no wait可以禁止可以禁止.2006年4月共享存儲(chǔ)編程45/108for(i=0;in;i+) ai = ai + bi;#pragma omp parallel int id, i, nthrds, istart, iend; id = omp_get_thread_num(); nthrds = omp_get_n
43、um_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;串行代碼用并行區(qū)實(shí)現(xiàn)并行化用任務(wù)分割構(gòu)造實(shí)現(xiàn)并行化對(duì)于do結(jié)構(gòu)與parallel結(jié)構(gòu)的比較同理,且以后討論若無(wú)特別說(shuō)明均基于c描述.2006年4月共享存儲(chǔ)編程46/108z 并行區(qū)和任務(wù)分割是openmp兩類基本的并行性構(gòu)造;z 并
44、行區(qū)中的代碼對(duì)組內(nèi)的各線程是可見(jiàn)的,也即并行區(qū)內(nèi)的代碼由各線程同時(shí)執(zhí)行;z 任務(wù)分割與并行區(qū)不同,它是將一個(gè)整體任務(wù)按負(fù)載平衡的方式分配給各線程來(lái)互相配合完成.z 并行區(qū)是并行的先決條件,任務(wù)分割必須要與并行區(qū)一起使用才能生效;z 并行區(qū)構(gòu)造為!omp parallel;z 任務(wù)分割構(gòu)造有:do/for,section,和single三種.根進(jìn)程并行區(qū)2006年4月共享存儲(chǔ)編程47/108z #pragma omp for clause clause . new-lineyfor-loopz clause可是下列說(shuō)明可是下列說(shuō)明:yprivate(list)yfirstprivate(list
45、)ylastprivate(list)yreduction(operator: list)yorderedyschedule(kind, chunk_size)ynowait后面將詳細(xì)后面將詳細(xì)說(shuō)明說(shuō)明2006年4月共享存儲(chǔ)編程48/108z !$omp do clause, clause.z do_loopz !$omp end do nowaityprivate(list)yfirstprivate(list)ylastprivate(list)yreduction(operator|intrinsic_procedure_name:list)yschedule(type,chunk)yo
46、rdered2006年4月共享存儲(chǔ)編程49/108z 循環(huán)體必須緊接在do或for之后.z for循環(huán)必須為一結(jié)構(gòu)化塊,且其執(zhí)行不被break語(yǔ)句中斷.z 在fortran中,如果寫上end do制導(dǎo)語(yǔ)句,其必須要緊跟在do循環(huán)的結(jié)束之后.z 循環(huán)變量必須為整形.z schedule, ordered,nowait子句只能出現(xiàn)一次.2006年4月共享存儲(chǔ)編程50/108z scheduleschedule子名決定循環(huán)如何在各線程中進(jìn)行分配子名決定循環(huán)如何在各線程中進(jìn)行分配: :z schedule(dynamic,chunk)y各線程每次得到chunk_size大小的任務(wù),執(zhí)行完后繼續(xù)取得任務(wù)
47、,以此反復(fù),直至任務(wù)完成(最后一任務(wù)可能會(huì)小于chunk_size).(任務(wù)池)y當(dāng)chunk_size未被指定時(shí),默認(rèn)為1.z schedule(static,chunk)y如果chunk_size被指定, 則各線程按線程號(hào)順序每人每得chunk次的循環(huán)任務(wù),如果任務(wù)不能一次平分掉,則分配循環(huán)進(jìn)行.y如果chunk_size未被指定,則各線程任務(wù)數(shù)即為循環(huán)數(shù)除以所用線程數(shù)的結(jié)果.z schedule(guided,chunk)y開(kāi)始以一大的單位進(jìn)行分配憶,逐漸減小到chunk指定的值.z schedule(runtime)y分配方式與chunk值大小取決于環(huán)境變量omp_schedule的設(shè)
48、置.z chunk以循環(huán)次數(shù)為單位.z 示意圖見(jiàn)下頁(yè).2006年4月共享存儲(chǔ)編程51/108work poolwork.dynamic方式static方式執(zhí)行時(shí)間guided方式work.2006年4月共享存儲(chǔ)編程52/108z 靜態(tài):適用于大部分情形.y特點(diǎn):x各線程任務(wù)明確,在任務(wù)分配時(shí)無(wú)需同步操作.x運(yùn)行快的線程需等慢的線程為:z 動(dòng)態(tài):適用于任務(wù)數(shù)量可變或不確定的情形(如條件收斂循環(huán)).y特點(diǎn):x各線程將要執(zhí)行的任務(wù)不可預(yù)見(jiàn),任務(wù)分配需同步操作.z guided:線程異步到達(dá)for結(jié)構(gòu)y特點(diǎn):x首先到達(dá)的線程總是分得q=ceiling(n/p)次循環(huán),然后n=max(n-q,p*k),
49、循環(huán)分配,直到n=p*k為止.z 環(huán)境變量:無(wú)需重新編譯程序,可根據(jù)原始輸入數(shù)據(jù)的情況改變?nèi)蝿?wù)分配策略.2006年4月共享存儲(chǔ)編程53/108c$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 parallel 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
50、(i)+b(i) enddoc$omp end doc$omp end parallel隱式隱式barrierno barrier默認(rèn)循環(huán)變量默認(rèn)循環(huán)變量i為私有線程私有類型變量為私有線程私有類型變量end do必須緊隨enddo,可省略.2006年4月共享存儲(chǔ)編程54/108#pragma omp parallel #pragma omp for for(i=1;in;i+) a(i)= cos(a(i); #pragma omp for for(i=1;in;i+) b(i)=a(i)+b(i); 為并行區(qū).隱式隱式barrier#pragma omp parallel #pragma o
51、mp 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月共享存儲(chǔ)編程55/108z sections用于程序中大范圍的非迭代執(zhí)行代碼段間的并行化.(如前10行和后10行間代碼間無(wú)依賴關(guān)系,可以并行.)缺省時(shí)每一個(gè)缺省時(shí)每一個(gè)“omp sections”構(gòu)造結(jié)束后有一個(gè)構(gòu)造結(jié)束后有一個(gè)barrier同步操作同步操作.通過(guò)通過(guò)使用使用 “nowait” 子句禁止隱式子句禁止隱式barrier同步同步(在構(gòu)造語(yǔ)句后直接加即
52、可在構(gòu)造語(yǔ)句后直接加即可).與與for結(jié)構(gòu)相類似結(jié)構(gòu)相類似,openmp也提供也提供parallel sections.#pragma omp sections no waitx_calculation();#pragma omp sectiony_calculation();#pragma omp sectionz_calculation();x_calculation(),y_calculation()以及z_calculation()代表三部分之間無(wú)依賴關(guān)系 的非循環(huán)代碼段.實(shí)質(zhì)上它們各代表很多行代碼.2006年4月共享存儲(chǔ)編程56/108z single:強(qiáng)制并行區(qū)中某些代碼以串行方式
53、執(zhí)行強(qiáng)制并行區(qū)中某些代碼以串行方式執(zhí)行y#pragma omp single clause clause . new-linexstructured-blockyclause is one of the following:xprivate(list)xfirstprivate(list)xnowait2006年4月共享存儲(chǔ)編程57/108zfortrany doy sectionsy singley worksharezcy fory sectionsy single2006年4月共享存儲(chǔ)編程58/108binding并行結(jié)構(gòu)的聯(lián)合使用并行結(jié)構(gòu)的聯(lián)合使用#pragma omp paralle
54、l 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如果不位于并行區(qū)內(nèi)或不與并行區(qū)聯(lián)合使用,便不起任何作用. 2006年4月共享存儲(chǔ)編程59/108!$omp parallel sections clause, clause.!$omp section block!$omp sectionblock. . .!$omp end parallel sections!$o
55、mp parallel do clause, clause.do_loop!$omp end parallel do!$omp parallel workshare clause, clause.block!$omp end parallel workshare2006年4月共享存儲(chǔ)編程60/108#pragma omp parallel for clause clause . new-linefor-loop#pragma omp parallel sections clause clause . new-line#pragma omp section new-linestructured-
56、block#pragma omp section new-linestructured-block.2006年4月共享存儲(chǔ)編程61/108z openmp主要有五類結(jié)構(gòu)化塊:y并行區(qū)parallel regionsy任務(wù)分割worksharingy數(shù)據(jù)環(huán)境data environmenty同步同步synchronizationy運(yùn)行時(shí)函數(shù)運(yùn)行時(shí)函數(shù)/環(huán)境變量2006年4月共享存儲(chǔ)編程62/108z 共享變量編程模型共享變量編程模型:y 大部分變量默認(rèn)為共享類型大部分變量默認(rèn)為共享類型z 各線程共享全局變量各線程共享全局變量y fortran: common 塊塊, save 變量變量, mod
57、ule 變量變量y c: file scope variables, staticz 但并不是所有變量全部共享但并不是所有變量全部共享.y 在并行區(qū)內(nèi)調(diào)用的子程序中的棧變量是私有在并行區(qū)內(nèi)調(diào)用的子程序中的棧變量是私有y 在語(yǔ)句塊中的在語(yǔ)句塊中的auto變量為私有變量變量為私有變量.2006年4月共享存儲(chǔ)編程63/108subroutine workcommon /input/ a(10)real temp(10)integer countsave countprogram sortcommon /input/ a(10)integer index(10)call inputc$omp para
58、llelcall work(index)c$omp end parallelprint*, index(1)變量a,index和cound為所有線程共享.temp為線程私有變量,各線程間到不可見(jiàn).2006年4月共享存儲(chǔ)編程64/108z 變量類型編譯制導(dǎo)變量類型編譯制導(dǎo): : threadprivate:將某些全局變量或數(shù)據(jù)區(qū)變?yōu)榫€程私有.z 通過(guò)下列類型屬性子句來(lái)改變變量類型:y shared(并行區(qū)結(jié)構(gòu))y privatey firstprivatey lastprivate:循環(huán)體內(nèi)的私有變量可以轉(zhuǎn)變?yōu)槿肿兞垦h(huán)體內(nèi)的私有變量可以轉(zhuǎn)變?yōu)槿肿兞? , 在循在循環(huán)結(jié)束后訪問(wèn)環(huán)結(jié)束后訪問(wèn);
59、z 默認(rèn)數(shù)據(jù)類型狀態(tài)可以改變默認(rèn)數(shù)據(jù)類型狀態(tài)可以改變:y default (private | shared | none)2006年4月共享存儲(chǔ)編程65/108z 變量私有化是openmp采用的重要的編譯技術(shù).y變量私有化;y私有變量初始化:xcopyinxfirstprivatey私有變量返回:xreductionxlastprivatez openmp私有類型變量是指并行區(qū)內(nèi)的只能被線程組內(nèi)的某一線程訪問(wèn)的變量.z openmp的私有變量包括:y并行區(qū)內(nèi)定義的變量;y由threadprivate 制導(dǎo)語(yǔ)句指明的變量;y由private, firstprivate,lastprivate,
60、 or reduction 子句指定的變量;y循環(huán)控制變量.2006年4月共享存儲(chǔ)編程66/108 parameter (n=1000) real a(n,n)c$omp threadprivate(/buf/) common/buf/lft(n),rht(n)c$omp parallel call init call scale call 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 subro
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 公益助學(xué)資金管理制度
- 云計(jì)算與網(wǎng)絡(luò)服務(wù)的整合策略試題及答案
- 公司禮品收發(fā)管理制度
- 信息系統(tǒng)監(jiān)理師考試重點(diǎn)復(fù)習(xí)試題及答案
- 養(yǎng)老機(jī)構(gòu)資金管理制度
- 幼兒園音體室管理制度
- 信息系統(tǒng)監(jiān)理師備考經(jīng)驗(yàn)交流試題及答案
- 小學(xué)紀(jì)律班級(jí)管理制度
- 平安工地監(jiān)理管理制度
- 醫(yī)院護(hù)理效期管理制度
- 家具維保服務(wù)投標(biāo)方案
- 環(huán)保管家服務(wù)投標(biāo)方案(技術(shù)標(biāo))
- 財(cái)經(jīng)素養(yǎng)知識(shí)考試題庫(kù)(濃縮500題)
- 離婚協(xié)議書(shū)電子版標(biāo)準(zhǔn)模板10篇
- 心理健康教育概論智慧樹(shù)知到課后章節(jié)答案2023年下南昌大學(xué)
- 電氣工程概論-肖登明
- 民間個(gè)人借款還清證明范本
- AOI設(shè)備評(píng)估報(bào)告
- 工程樹(shù)木砍伐施工方案范本
- Sibelius使用教程教材說(shuō)明
- 柔力球-華中師范大學(xué)中國(guó)大學(xué)mooc課后章節(jié)答案期末考試題庫(kù)2023年
評(píng)論
0/150
提交評(píng)論