多核程序設(shè)計(jì):OpenMP總結(jié)及程序演示_第1頁
多核程序設(shè)計(jì):OpenMP總結(jié)及程序演示_第2頁
多核程序設(shè)計(jì):OpenMP總結(jié)及程序演示_第3頁
多核程序設(shè)計(jì):OpenMP總結(jié)及程序演示_第4頁
多核程序設(shè)計(jì):OpenMP總結(jié)及程序演示_第5頁
已閱讀5頁,還剩81頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、1OpenMP總結(jié)及程序演示2其他的編譯指導(dǎo)語句及子句Single子句:用來指定某塊程序由一個(gè)線程執(zhí)行在此線程執(zhí)行期間,其他線程都處于等待狀態(tài),直到single語句塊結(jié)束處隱含的同步屏障格式:#pragma omp singleclause,clause block3#pragma omp parallel num_threads(4) printf(parallel region before single. thread %dn,omp_get_thread_num(); #pragma omp single printf(single region by thread %d.n,omp_

2、get_thread_num(); printf(parallel region after single. thread %d.n,omp_get_thread_num();4其他的編譯指導(dǎo)語句及子句Master子句:用于指定一個(gè)程序塊在主線程中運(yùn)行沒有隱含的同步屏障,主線程在執(zhí)行master程序塊的時(shí)候,其他線程可以繼續(xù)執(zhí)行,不必等待。5#pragma omp parallel num_threads(4) printf(parallel region before master. thread %dn,omp_get_thread_num(); #pragma omp master pr

3、intf(“master region by thread %d.n,omp_get_thread_num(); printf(parallel region after master. thread %d.n,omp_get_thread_num();6其他的編譯指導(dǎo)語句及子句If子句:有條件并行化格式:if(scalar-expression)舉例:#pragma omp parallel if(n10) printf(“if clause, ThreadId=%dn”, omp_get_thread_num(); 如果n10,則大括號內(nèi)代碼并行執(zhí)行;如果n=10,則大括號內(nèi)代碼串行執(zhí)行7

4、其他的編譯指導(dǎo)語句及子句Schedule子句:格式:schedule(type,size)type參數(shù):dynamic/guided/runtime/staticsize參數(shù):表示循環(huán)迭代次數(shù),必須為整數(shù)。如果type參數(shù)為dynamic/guided/static,則size為可選參數(shù)如果type參數(shù)為runtime,則不需要使用size參數(shù)。8其他的編譯指導(dǎo)語句及子句Schedule子句:靜態(tài)調(diào)度(static):parallel for語句不帶schedule子句,默認(rèn)為靜態(tài)調(diào)度方式。動態(tài)調(diào)度(dynamic):沒有size參數(shù):將迭代逐個(gè)分配到各個(gè)線程;使用size參數(shù):每次分配給線程

5、的迭代次數(shù)為size次。啟發(fā)式自調(diào)度(guided):開始時(shí)每個(gè)線程會分配到較大的迭代塊,之后分配到的迭代塊會遞減。迭代塊的大小按指數(shù)級下降到指定的size大小。如果沒有size參數(shù),默認(rèn)1。96.1 OpenMP編程簡介面向共享內(nèi)存以及分布式共享內(nèi)存的多處理器多線程并行編程語言。一種編譯指導(dǎo)語句,能夠顯式指導(dǎo)多線程、共享內(nèi)存并行的應(yīng)用程序編程接口(API)具有良好的可移植性,支持多種編程語言,如:Fortran77,F(xiàn)ortran90,F(xiàn)ortran95,C/C+支持多種平臺大多數(shù)的類UNIX系統(tǒng)以及Windows NT系統(tǒng)(Windows 2000,Windows XP,Windows V

6、ista等)。106.1.1 體系結(jié)構(gòu)共享內(nèi)存多處理器內(nèi)存是共享的,處理器在訪問內(nèi)存的時(shí)候使用的是相同的內(nèi)存編址空間,某一個(gè)處理器寫入內(nèi)存的數(shù)據(jù)會立刻被其它處理器訪問到。分布式共享內(nèi)存也屬于共享內(nèi)存多處理器結(jié)構(gòu),將多機(jī)的內(nèi)存資源通過虛擬化的方式形成一個(gè)統(tǒng)一的內(nèi)存空間提供給多機(jī)上的處理器使用116.1.2 OpenMP編程基礎(chǔ)OpenMP的編程模型以線程為基礎(chǔ),通過編譯指導(dǎo)語句來顯式地指導(dǎo)并行化,為編程人員提供對并行化的完整控制。OpenMP多線程編程的基礎(chǔ)知識OpenMP程序的執(zhí)行模型OpenMP程序中涉及的編譯指導(dǎo)語句和庫函數(shù)OpenMP程序的執(zhí)行環(huán)境6.1.2 OpenMP編程基礎(chǔ)Open

7、MP程序采用Fork-Join的執(zhí)行模式 Master ThreadParalllRegionNestedParallelRegion13OpenMP的功能由兩種形式提供編譯指導(dǎo)語句運(yùn)行時(shí)庫函數(shù)通過環(huán)境變量的方式靈活控制程序的運(yùn)行,例如:通過OMP_NUM_THREADS值來控制運(yùn)行線程的數(shù)目。14編譯指導(dǎo)語句在編譯器編譯程序的時(shí)候,會識別特定的注釋這些注釋就包含著OpenMP程序的一些語義OpenMP的所有編譯指導(dǎo)語句以#pragma omp 開始,后面跟具體的功能指令,形式:#pragma omp clause , clause其中directive部分就包含了具體的編譯指導(dǎo)語句,包括pa

8、rallel, for, parallel for, section, sections, single, master, critical, flush, ordered和atomic。編譯指導(dǎo)語句完成任務(wù)分配和同步等功能后面的可選子句clause給出了相應(yīng)的編譯指導(dǎo)語句的參數(shù),子句 可以影響到編譯指導(dǎo)語句的具體行為。每一個(gè)編譯指導(dǎo)語句都有一系列適合它的子句有5個(gè)編譯指導(dǎo)語句不能跟相應(yīng)的子句: master, critical, flush, ordered, atomic在無法識別OpenMP語義的普通編譯器中,這些注釋被忽略O(shè)penMP程序能夠同時(shí)被普通編譯器和支持OpenMP的編譯器處

9、理用戶可以用同一份代碼來編寫串行或并行程序方便把串行程序改編為并行程序16運(yùn)行時(shí)庫函數(shù)OpenMP運(yùn)行時(shí)函數(shù)庫原本用以設(shè)置和獲取執(zhí)行環(huán)境相關(guān)的信息,它們當(dāng)中也包含一系列用以同步的APIOpenMP運(yùn)行時(shí)函數(shù)庫的使用類似于相應(yīng)編程語言內(nèi)部的函數(shù)調(diào)用,在沒有庫支持的編譯器上無法正確識別OpenMP程序。這是庫函數(shù)和編譯指導(dǎo)語句不同的地方。使用運(yùn)行時(shí)庫函數(shù)所包含的函數(shù),必須在相應(yīng)的源文件中包含OpenMP頭文件omp.h 運(yùn)行函數(shù)庫在不同的平臺上由不同格式提供支持。Windows平臺通過動態(tài)鏈接庫提供UNIX平臺同時(shí)提供動態(tài)鏈接庫和靜態(tài)鏈接庫。17OpenMP程序?qū)嵗?#include “stdaf

10、x.h”#include “omp.h”int _tmain(int argc, _TCHAR* argv) printf(“Hello from serial.n”); printf(“Thread number = %dn”,omp_get_thread_num(); /串行 #pragma omp parallel /開始并行執(zhí)行 printf(“Hello from parallel. Thread number=%dn”,omp_get_thread_num();printf(“Hello from serial again.n”);return 0;18OpenMP應(yīng)用程序構(gòu)成結(jié)合

11、了兩種并行編程的方式編譯指導(dǎo)語句,在編譯過程并行化代碼,是OpenMP組成中最重要的部分,也是編寫OpenMP程序的關(guān)鍵運(yùn)行時(shí)庫函數(shù),在運(yùn)行時(shí)對并行環(huán)境支持OpenMP應(yīng)用程序的組成部分 環(huán)境變量是動態(tài)函數(shù)庫中用來控制函數(shù)運(yùn)行的參數(shù)19使用Visual Studio 2005編寫OpenMP程序當(dāng)前的Visual Studio .Net 2005完全支持OpenMP 2.0標(biāo)準(zhǔn),通過編譯器選項(xiàng) /openmp來支持OpenMP程序的編譯和鏈接20在Microsoft Visual Studio .Net 2005環(huán)境下面編寫OpenMP程序的必要步驟1)生成Console項(xiàng)目;2)配置項(xiàng)目,使

12、之支持OpenMP;3)編寫代碼,加入#include “omp.h”;4)編寫源程序;5)配置環(huán)境變量OMP_NUM_THREADS,確定線程數(shù)目;6)執(zhí)行程序。OMP_NUM_THREADS=4OMP_NUM_THREADS=223設(shè)置環(huán)境OMP_NUM_THREADS的值24使用Visual Studio 2005編寫OpenMP程序OpenMP程序使用到的環(huán)境變量OMP_NUM_THREADS設(shè)置為4默認(rèn)的情況下OMP_NUM_THREADS=系統(tǒng)中邏輯CPU的數(shù)目在雙核的系統(tǒng)中OMP_NUM_THREADS=2雙核超線程的邏輯CPU的數(shù)目為4,256.2 OpenMP編程技術(shù)循環(huán)并行

13、化編譯指導(dǎo)語句的格式#pragma omp parallel for clauseclausefor( index = first ; test_expression ; increment_expr)body of the loop;1 循環(huán)并行化:使用OpenMP并行程序的重要部分26循環(huán)并行化語句工作原理將for循環(huán)中的工作分配到一個(gè)線程組中,線程組中的每一個(gè)線程將完成循環(huán)中的一部分內(nèi)容;for循環(huán)語句要緊跟在parallel for的編譯指導(dǎo)語句后面,編譯指導(dǎo)語句的功能區(qū)域一直延伸到for循環(huán)語句的結(jié)束;編譯指導(dǎo)語句后面的字句(clause)用來控制編譯指導(dǎo)語句的具體行為。27循環(huán)并行

14、化語句的限制循環(huán)并行化語句的限制并行化的語句必須是for循環(huán)語句具有規(guī)范的格式能夠推測出循環(huán)的次數(shù)循環(huán)并行化的語句必須具有如下的形式:for (index = start ; index end ; increment_expr)index必須是一個(gè)整數(shù)小于號()也可以被其它的比較操作符替代start和end可以是任意的數(shù)值表達(dá)式,但是在循環(huán)的過程中其值不能改變,以保證能夠在循環(huán)之前就計(jì)算出循環(huán)的次數(shù)。increment_expr形式如下,其中incr是一個(gè)在循環(huán)過程中不變的數(shù)值表達(dá)式28簡單循環(huán)并行化 將兩個(gè)向量相加,并將計(jì)算的結(jié)果保存到第三個(gè)向量中,向量的維數(shù)為n for(int i=0;

15、 in; i+) zi = xi+yi;各個(gè)分量之間沒有數(shù)據(jù)相關(guān)性循環(huán)計(jì)算的過程也沒有循環(huán)依賴性 程序進(jìn)行循環(huán)并行化: #pragma omp parallel for for(int i=0; in; i+) zi = xi+yi;數(shù)據(jù)相關(guān)的概念實(shí)例: x0 = 0; y0 = 1; #pragma omp parallel for private(k) for (k = 1; k 100; k+) xk = yk-1 + 1; /S1 yk = xk-1 + 2; /S2 程序段2程序段2運(yùn)行結(jié)果32循環(huán)嵌套在一個(gè)循環(huán)體內(nèi)經(jīng)常會包含另外一個(gè)循環(huán)體,循環(huán)產(chǎn)生了嵌套循環(huán)并行化編譯指導(dǎo)語句可以加

16、在任意一個(gè)循環(huán)之前對應(yīng)的最近的循環(huán)語句被并行化,其它部分保持不變 int i;int j #pragma omp parallel for private(j) for(i=0;i2;i+) for(j=6;j10;j+) printf(“i=%d j=%dn”,i,j);33循環(huán)嵌套比較(程序段3、4)int i;int j#pragma omp parallel for private(j)for(i=0; i2; i+) for(j=6; j10; j+) printf(“ i=%d j=%dn”, i, j);執(zhí)行結(jié)果: i=0 j=6 i=1 j=6 i=0 j=7 i=1 j=7

17、i=0 j=8 i=1 j=8 i=1 j=9 i=0 j=9int i;int j;for(i=0; i2; i+)#pragma omp parallel forfor(j=6; j10; j+) printf(i=%d j=%d n, i, j);執(zhí)行結(jié)果: i=0 j=6 i=0 j=8 i=0 j=9 i=0 j=7 i=1 j=6 i=1 j=8 i=1 j=7 i=1 j=934程序段3、435去掉private子句36控制數(shù)據(jù)的共享屬性 OpenMP程序在同一個(gè)共享內(nèi)存空間上執(zhí)行可以任意使用這個(gè)共享內(nèi)存空間上的變量進(jìn)行線程間的數(shù)據(jù)傳遞內(nèi)存分布結(jié)構(gòu)如圖每一個(gè)線程的??臻g都是私有的

18、全局變量以及程序代碼都是全局共享動態(tài)分配的堆空間也是共享的通過threadprivate指出的數(shù)據(jù)結(jié)構(gòu)在每一個(gè)線程中都會有一個(gè)副本 shared定義變量作用域是共享的private私有的 線程1棧線程2棧堆程序代碼程序數(shù)據(jù)37int gval=8;void funcb(int * x, int *y, int z)static int sv;int u;u=(*y)*gval;*x=u+z;void funca(int * a, int n)int i;int cc=9;#pragma omp parallel forfor(i=0;in;i+)int temp=cc;funcb(&ai,&t

19、emp,i);函數(shù)funca調(diào)用了funcb,并且在函數(shù)funca中使用了OpenMP進(jìn)行并行化全局變gval是共享的在funca函數(shù)的內(nèi)部,變量i由于是循環(huán)控制變量,因此是線程私有的cc在并行化語句外聲明,是共享的temp在循環(huán)并行化語句內(nèi)部的自動變量,是線程私有的輸入的指針變量a以及n是共享的,都在循環(huán)并行化語句之外聲明在函數(shù) funcb內(nèi)部,靜態(tài)變量sv是共享的,在程序內(nèi)存空間中只有一份,因此,在這種使用方式下會引起數(shù)據(jù)沖突變量u是自動變量,由于被并行線程調(diào)用,是線程私有的參數(shù)x的本身是私有的指針變量,但是*x指向的內(nèi)存空間是共享的,其實(shí)際參數(shù)即函數(shù)funca中的a數(shù)組參數(shù)y的本身是私有

20、的指針變量,指向的*y也是私有的,其實(shí)際內(nèi)存空間即私有的temp占用的空間數(shù)值參數(shù)z是線程私有的。 私有變量的初始化和終結(jié)操作循環(huán)并行化開始時(shí)訪問到私有變量在主線程中的同名變量的值,也有可能需要將循環(huán)并行化最后一次循環(huán)的變量結(jié)果返回給主線程中的同名的變量。OpenMP 編譯指導(dǎo)語句使用firstprivate和 lastprivate對這兩種需求進(jìn)行支持,使得循環(huán)并行開始執(zhí)行的時(shí)候私有變量通過主線程中的變量初始化,同時(shí)循環(huán)并行結(jié)束的時(shí)候,將最后一次循環(huán)的相應(yīng)變量賦值給主線程的變量。程序?qū)嵗?39私有變量的初始化和終結(jié)操作 firstprivate和lastprivate ( 程序段7)int

21、 val=8;#pragma omp parallel for firstprivate(val) lastprivate(val)for(int i=0;i2;i+)printf(i=%d val=%dn,i,val);if(i=1)val=10000;printf(i=%d val=%dn,i,val);printf(val=%dn,val);40程序段7變化 41int val=8;#pragma ompfor(int i=0;i5;i+) printf(i,val,thread); if(i=2) val=10000; if(i=3) val=11111; printf(i,val,t

22、hread);i=0,vali=1,vali=2,val并行i=3,vali=4,valval ? ? ?私有變量需要初始化任務(wù)劃分方式val環(huán)境變量42去掉lastprivate 正常運(yùn)行結(jié)果43去掉firstprivate,lastprivate44使用private子句456.2.2 并行區(qū)域編程循環(huán)并行化實(shí)際上是并行區(qū)域編程的一個(gè)特例,本節(jié)介紹非循環(huán)的并行區(qū)域編程并行區(qū)域簡單說就是通過循環(huán)并行化編譯指導(dǎo)語句使得一段代碼能夠在多個(gè)線程內(nèi)部同時(shí)執(zhí)行。并行區(qū)域編譯指導(dǎo)語句的格式 #pragma omp parallel clauseclauseblockblock是需要在多個(gè)線程中執(zhí)行的代碼

23、塊,每一個(gè)線程在遇到并行區(qū)域的編譯指導(dǎo)語句時(shí),都會同時(shí)執(zhí)行跟隨其后的程序代碼塊。在該語句后面可以跟隨一些子句,包括private, shared, default, reduction, if ,copyin6.2.2 并行區(qū)域編程parallel編譯指導(dǎo)語句的執(zhí)行過程(程序段9、10)#pragma omp parallelfor(int i=0;i5;i+) printf(hello world i=%dn,i);#pragma omp parallel forfor(int i=0;i5;i+) printf(hello world i=%dn,i);6.2.2 并行區(qū)域編程程序段9的執(zhí)

24、行結(jié)果hello world i=0hello world i=0hello world i=1hello world i=1hello world i=2hello world i=2hello world i=3hello world i=3hello world i=4hello world i=4程序段10的執(zhí)行結(jié)果hello world i=0hello world i=3hello world i=1hello world i=4hello world i=26.2.2 并行區(qū)域編程并行區(qū)域與循環(huán)并行化的區(qū)別并行區(qū)域采用復(fù)制的執(zhí)行方式,將代碼在所有的線程內(nèi)部都執(zhí)行一次循環(huán)并行化采用

25、工作分配的執(zhí)行方式,將循環(huán)所需要所有工作量按照一定的方式分配到各個(gè)執(zhí)行線程中,所有線程執(zhí)行工作的總和是原先串行執(zhí)行所完成的工作量。并行區(qū)域parallel語句的作用:當(dāng)程序遇到parallel編譯指導(dǎo)語句時(shí),就會生成相應(yīng)數(shù)目(根據(jù)環(huán)境變量)的線程,且組成一個(gè)線程組,并將代碼重復(fù)地在各個(gè)線程內(nèi)部執(zhí)行。Parallel的末尾隱含一個(gè)同步障礙,所有線程完成各自的任務(wù)后將在這個(gè)同步障礙匯合。此時(shí),此線程組的主線程(master)繼續(xù)執(zhí)行,而相應(yīng)的子線程(slave)則停止執(zhí)行。496.2.2 并行區(qū)域編程線程私有數(shù)據(jù)與threadprivate子句(程序段11)使用threadprivate子句用來標(biāo)

26、明某一個(gè)變量是線程私有數(shù)據(jù),在程序運(yùn)行過程中,不能被其它線程訪問。int counter=0; /using threadprivate#pragma omp threadprivate(counter)void inc_counter()counter+; int _tmain(int argc, TCHAR * argv)#pragma omp parallel for(int i=0;i10000;i+)inc_counter();printf(counter=%dn,counter); 506.2.2 并行區(qū)域編程線程私有數(shù)據(jù)與copyin子句(程序段12)使用copyin子句對線程私

27、有的全局變量進(jìn)行初始化。int global=0;#pragma omp threadprivate(global)int _tmain(int argc, TCHAR * argv)global=1000;#pragma omp parallel copyin(global) printf(global=%dn,global); global=omp_get_thread_num(); printf(global=%dn,global);printf(parallel againn);#pragma omp parallelprintf(global=%dn,global); 51程序段12

28、52程序段12(變化)運(yùn)行結(jié)果正常運(yùn)行結(jié)果 去掉threadprivate, copyin子句53程序段12(變化)運(yùn)行結(jié)果正常運(yùn)行結(jié)果 只去掉copyin子句54程序段12(變化)運(yùn)行結(jié)果使用private子句 使用firstprivate子句lastprivate不能使用(僅對for,sections)55并行區(qū)域之間的工作共享工作隊(duì)列工作隊(duì)列的基本工作過程即維持一個(gè)工作的隊(duì)列,線程在并行執(zhí)行的時(shí)候,不斷從這個(gè)隊(duì)列中取出相應(yīng)的工作完成,直到隊(duì)列為空為止。根據(jù)線程號分配任務(wù)由于每一個(gè)線程在執(zhí)行的過程中的線程標(biāo)識號是不同的,可以根據(jù)這個(gè)線程標(biāo)識號來分配不同的任務(wù)編譯指導(dǎo)語句實(shí)現(xiàn)方法直接使用編譯

29、指導(dǎo)語句for將任務(wù)分配到各個(gè)線程用sections編譯指導(dǎo)語句以及section子句自然地將不同的工作任務(wù)編寫成不同的代碼片段并行執(zhí)行并行區(qū)域之間的工作共享程序13int next_task=0; int get_next_task() int task; #pragma omp criticalif(next_task8) task=next_task; next_task+; else task=-1; return task; void task_queue() int my_task; #pragma omp parallel private(my_task) my_task=get

30、_next_task(); while(my_task!=-1) get_task_done(my_task); my_task=get_next_task(); 并行區(qū)域之間的工作共享根據(jù)線程號分配任務(wù):由于每一個(gè)線程在執(zhí)行的過程中的線程標(biāo)識號是不同的,可以根據(jù)這個(gè)線程標(biāo)識號來分配不同的任務(wù)。#pragma omp parallel private(myid) nthreads=omp_get_num_threads(); myid=omp_get_thread_num(); get_my_work_done(myid,nthreads); 58并行區(qū)域之間的工作共享使用循環(huán)語句分配任務(wù)(程

31、序段15)#pragma omp parallel printf(outside loop thread=%dn, omp_get_thread_num(); #pragma omp for for(int i=0;i4;i+)printf(inside loop i=%d thread=%dn, i, omp_get_thread_num();59程序段15運(yùn)行結(jié)果去掉#pragma omp for60并行區(qū)域之間的工作共享工作分區(qū)編碼(程序段16)#pragma omp parallel sections #pragma omp section printf(section 1 threa

32、d=%dn,omp_get_thread_num(); #pragma omp sectionprintf(section 2 thread=%dn,omp_get_thread_num(); #pragma omp sectionprintf(sectino 3 thread=%dn,omp_get_thread_num();并行區(qū)域之間的工作共享執(zhí)行結(jié)果: section 1 thread=0 section 2 thread=1 section 3 thread=0各個(gè)線程自動從各個(gè)分區(qū)中獲得任務(wù)執(zhí)行,在執(zhí)行完一個(gè)分區(qū)的時(shí)候如果分區(qū)組里還有未完成的工作,則繼續(xù)取得任務(wù)完成626.2.3

33、OpenMP線程同步OpenMP支持兩種不同類型的線程同步機(jī)制互斥鎖:用來保護(hù)一塊共享的存儲空間,使得每次訪問這塊空間的線程最多只有一個(gè),保證了數(shù)據(jù)的完整性事件通知機(jī)制:保證多個(gè)線程之間的執(zhí)行順序數(shù)據(jù)競爭 int i; int max_num=-1; #pragma omp parallel for for(i=0; imax_num) max_num=ari;63OpenMP線程同步互斥鎖機(jī)制互斥鎖機(jī)制在OpenMP中,提供了三種不同的互斥鎖機(jī)制用來對一塊內(nèi)存進(jìn)行保護(hù),它們分別是: (1) 臨界區(qū)(critical) (2) 原子操作(atomic) (3) 庫函數(shù)來提供同步操作64Open

34、MP線程同步臨界區(qū)在程序需要訪問可能產(chǎn)生競爭的內(nèi)存數(shù)據(jù)的時(shí)候,都需要插入相應(yīng)的臨界區(qū)代碼。臨界區(qū)編譯指導(dǎo)語句的格式如下所示: #pragma omp critical (name) block65OpenMP線程同步臨界區(qū)int i; int max_num_x=max_num_y=-1;#pragma omp parallel forfor(i=0;imax_num_x) max_num_x=arxi; #pragma omp critical (max_ary) if(aryimax_num_y) max_num_y=aryi; 66OpenMP線程同步原子操作只能作用在語言內(nèi)建的基本數(shù)據(jù)

35、結(jié)構(gòu)(程序段18)。#pragma omp atomic 或者 #pragma omp atomicx =expr x+/or x-, -x, +x int counter=0; #pragma omp parallel for(int i=0;i10000;i+) #pragma omp atomic /atomic operation counter+; printf(counter = %dn,counter);67OpenMP運(yùn)行時(shí)庫函數(shù)的互斥鎖支持去掉#pragma omp atomicOMP_NUM_THREADS=468OpenMP運(yùn)行時(shí)庫函數(shù)的互斥鎖支持OpenMP通過一系列的

36、庫函數(shù)支持更加細(xì)致的互斥鎖操作編譯指導(dǎo)語句進(jìn)行的互斥鎖支持只能放置在一段代碼之前,作用在這段代碼之上。程序員必須自己保證在調(diào)用相應(yīng)鎖操作之后釋放相應(yīng)的鎖,否則就會造成多線程程序的死鎖。69OpenMP運(yùn)行時(shí)庫函數(shù)的互斥鎖支持omp_lock_t lock; /對應(yīng)程序?qū)嵗?int counter=0;void inc_counter() printf(thread id=%dn,omp_get_thread_num(); for(int i=0;i100000;i+) omp_set_nest_lock(&lock); counter+; omp_unset_nest_lock(&lock);

37、 70事件同步機(jī)制隱含的同步屏障 在每一個(gè)并行區(qū)域中都會有一個(gè)隱含的的同步屏障,線程組執(zhí)行完本區(qū)域代碼,則需要進(jìn)行同步。 一個(gè)同步屏障要求所有的線程都執(zhí)行到此屏障,容納后才能夠繼續(xù)執(zhí)行下面的代碼。 #pragma omp for #pragma omp sections71隱含的同步屏障程序?qū)嵗?程序段20) #pragma omp parallel #pragma omp for nowait for(int i=0;i9;+i) xi=(yi+zi)/2; printf(i=%d thread=%dn,i,omp_get_thread_num(); printf(finishedn); 7

38、2程序20運(yùn)行結(jié)果沒有nowait子句加上nowait子句73事件同步機(jī)制明確的同步屏障 有些情況,隱含的同步屏障不能提供有效的同步措施,因此需要明確的同步屏障語句。 #pragma omp parallel initialization ( ) ; #pragma omp barrier; process ( ) ; 74事件同步機(jī)制循環(huán)并行化中的順序語句 在某些情況下,對于循環(huán)并行化中的某些處理需要規(guī)定執(zhí)行的順序。例如:在一次循環(huán)的過程之中,一大部分的工作是可以并行執(zhí)行的,而其余的工作需要等到前面的工作全部完成后才能執(zhí)行。 在循環(huán)并行化的過程中可以使用ordered子句使順序執(zhí)行的語句能夠在前面的循環(huán)都執(zhí)行完畢之后再執(zhí)行。 #pragma omp ordered #pragma omp parallel for ordered schedule(dynamic)75程序?qū)嵗?7

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論