




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、精選優質文檔-傾情為你奉上精選優質文檔-傾情為你奉上專心-專注-專業專心-專注-專業精選優質文檔-傾情為你奉上專心-專注-專業高性能計算和網格技術實驗報告實驗題目OpenMP和MPI編程姓名學號專業計算機系統結構指導教師助教所在學院計算機科學與工程學院論文提交日期一、實驗目的本實驗的目的是通過練習掌握 OpenMP 和MPI 并行編程的知識和技巧。1、熟悉 OpenMP 和MPI 編程環境和工具的使用;2、掌握并行程序編寫的基本步驟;3、了解并行程序調試和調優的技巧。二、實驗要求1、獨立完成實驗內容;2、了解并行算法的設計基礎;3、熟悉OpenMP和MPI的編程環境以及運行環境;4、理解不同線
2、程數,進程數對于加速比的影響。三、實驗內容3.1、矩陣LU分解算法的設計:參考文檔sy6.doc所使用的并行算法:在LU分解的過程中,主要的計算是利用主行i對其余各行j,(ji)作初等行變換,各行計算之間沒有數據相關關系,因此可以對矩陣A按行劃分來實現并行計算。考慮到在計算過程中處理器之間的負載均衡,對A采用行交叉劃分:設處理器個數為p,矩陣A的階數為n,對矩陣A行交叉劃分后,編號為i(i=0,1,p-1)的處理器存有A的第i, i+p, i+(m-1)p行。然后依次以第0,1,n-1行作為主行,將其廣播給所有處理器,各處理器利用主行對其部分行向量做行變換,這實際上是各處理器輪流選出主行并廣播
3、。若以編號為my_rank的處理器的第i行元素作為主行,并將它廣播給所有處理器,則編號大于等于my_rank的處理器利用主行元素對其第i+1,m-1行數據做行變換,其它處理器利用主行元素對其第i,m-1行數據做行變換。根據上述算法原理用代碼表示如下(關鍵代碼):for(k = 0;kN;k+)for (i = 0; i THREADS_NUM; i+) thread_data_arrrayi.thread_id = i;thread_data_arrrayi.K_number = k;thread_data_arrrayi.chushu = akk;/創建線程rc = pthread_crea
4、te(&pidi, NULL, work, (void*)&thread_data_arrrayi); for (i = 0; i thread_id;/線程IDint myk = my_data-K_number;/外層循環計數Kfloat mychushu = my_data-chushu;/對角線的值int s, e;int i, j;s = (N-myk-1) * myid / THREADS_NUM;/確定起始循環的行數的相對位置e = (N-myk-1) * (myid + 1) / THREADS_NUM;/確定終止循環的行數的相對位置for (i = s+myk+1; i e+
5、myk+1; i+)/由于矩陣規模在縮小,找到偏移位置aimyk=aimyk/mychushu;for (j = myk+1; j N; j+)aij=aij-aimyk*amykj;/printMatrix(a);return NULL; 第一部分為入口函數,其創建指定的線程數,并根據不同的線程id按行劃分矩陣,將矩陣的不同部分作為參數傳遞給線程,在多處理器電腦上,不同的線程并行執行,實現并行計算LU分解。在LU分解的過程中,主要的計算是利用主行i對其余各行j,(j)i)做初等行變換,由于各行計算之間沒有數據相關關系,因此可以對矩陣按行劃分來實現并行算法。考慮到計算過程中處理器負載的均衡,對
6、矩陣采用行交叉劃分;假設處理器個數為p,矩陣的階數為n,則每個處理器處理的行數為。由于在OpenMP和MPI中并行算法的實現不太一樣,所以接下來的兩小節中我將分別針對兩個編程環境設計LU分解的并行實現。3.2、OpenMP編程 因為OpenMP是基于線程的編程模型,所以設計了一個基于多線程的OpenMP的LU分解算法,關鍵代碼如下:for(k = 0;kN;k+)omp_set_num_threads(THREADS_NUM);#pragma omp parallel private(tid)tid=omp_get_thread_num(); /當前線程IDint myid = tid;pri
7、ntf(hello world from OMP thread %d n,tid);int myk = k;float mychushu = Akk;int s, e;int i, j;s = (N-myk-1) * myid / THREADS_NUM;/確定起始循環的行數的相對位置e = (N-myk-1) * (myid + 1) / THREADS_NUM;/確定終止循環的行數的相對位置for (i = s+myk+1; i e+myk+1; i+)/由于矩陣規模在縮小,找到偏移位置Aimyk=Aimyk/mychushu;for (j = myk+1; j j的元素,其對角線上元素為
8、1.0,其它為0,U為Akj中k=j的元素,其余為0。這里如果我們使用的是一般的多線程編程,則在開啟THREAD _NUMS個線程后,在下次循環開始之前,需要手動配置等待線程同步,不然可能出現錯誤。但由于OpenMP使用Fork-Join并行執行模型,其會在線程隊執行完以后才轉到主線程執行,所以不需要等待線程同步。詳細的代碼請參看附帶源程序。3.3、MPI編程設處理器個數為p,矩陣A的階數為n,對矩陣A行交叉劃分后,編號為i(i=0,1,p-1)的處理器存有A的第i, i+p, i+ (m-1)p行。然后依次以第0,1,n-1行作為主行,將其廣播給所有處理器,各處理器利用主行對其部分行向量做行
9、變換,這實際上是各處理器輪流選出主行并廣播。若以編號為my_rank的處理器的第i行元素作為主行,并將它廣播給所有處理器,則編號大于等于my_rank的處理器利用主行元素對其第i+1,m-1行數據做行變換,其它處理器利用主行元素對其第i,m-1行數據做行變換,計算完成后,編號為0的處理器收集各處理器中的計算結果,并從經過初等行變換的矩陣A中分離出下三角矩陣L和上三角矩陣U。 關鍵代碼如下:/*0號進程采用行交叉劃分將矩陣A劃分為大小m*M的p塊子矩陣,依次發送給1至p-1號進程*/ if (my_rank=0) for(i=0;im;i+) for(j=0;jM;j+) a(i,j)=A(i*
10、p),j); for(i=0;iM;i+) if (i%p)!=0)i1=i%p;i2=i/p+1;MPI_Send(&A(i,0),M,MPI_FLOAT,i1,i2,MPI_COMM_WORLD); else for(i=0;im;i+) MPI_Recv(&a(i,0),M,MPI_FLOAT,0,i+1,MPI_COMM_WORLD,&status); for(i=0;im;i+) for(j=0;jp;j+)/*j號進程負責廣播主行元素*/if (my_rank=j)v=i*p+j;for (k=v;kM;k+)fk=a(i,k);MPI_Bcast(f,M,MPI_FLOAT,my
11、_rank,MPI_COMM_WORLD);elsev=i*p+j;MPI_Bcast(f,M,MPI_FLOAT,j,MPI_COMM_WORLD);/*編號小于my_rank的進程(包括my_rank本身)利用主行對其第i+1,m-1行數據做行變換*/if (my_rank=j)for(k=i+1;km;k+)a(k,v)=a(k,v)/fv;for(w=v+1;wj)for(k=i;km;k+)a(k,v)=a(k,v)/fv;for(w=v+1;wM;w+)a(k,w)=a(k,w)-fw*a(k,v); /*0號進程從其余各進程中接收子矩陣a,得到經過變換的矩陣A*/ if (my_
12、rank=0) for(i=0;im;i+) for(j=0;jM;j+) A(i*p,j)=a(i,j); if (my_rank!=0) for(i=0;im;i+) MPI_Send(&a(i,0),M,MPI_FLOAT,0,i,MPI_COMM_WORLD); else for(i=1;ip;i+) for(j=0;jm;j+)MPI_Recv(&a(j,0),M,MPI_FLOAT,i,j,MPI_COMM_WORLD,&status);for(k=0;kM;k+)A(j*p+i),k)=a(j,k); 3.4、程序調優:OpenMP和MPI混合編程 我們知道OpenMP是基于線程
13、的并行編程模型,一個共享存儲的進程由多個線程組成,OpenMP就是基于已有線程的共享編程模型;而MPI屬于消息傳遞的并行編程模型,這個從前兩小節中可以看到,因為在LU的MPI實現中,我們對矩陣采用交叉劃分,根據p(處理器號)劃分行,因此可以對每個劃分出來的矩陣采用多線程并行算法,也即可以采用OpenMP計算。 在MPI的編號大于等于my_rank的處理器利用主行元素對其第i+1,m-1行數據做行變換,其它處理器利用主行元素對其第i,m-1行數據做行變換部分采用OpenMP計算,所以混合編程的核心代碼如下:/*編號小于my_rank的進程(包括my_rank本身)利用主行對其第i+1,m-1行數
14、據做行變換*/if (my_rank=j)int tid;omp_set_num_threads(THREADS_NUM);#pragma omp parallel private(tid)tid = omp_get_thread_num();int myid = tid;int myk = i+1;float mychushu = fv;int s,e;int c,d;s = (m-myk-1)*myid/THREADS_NUM;e = (m-myk-1)*(myid+1)/THREADS_NUM;for(c=s+myk+1;ce+myk+1;c+)a(c,v)=a(c,v)/mychush
15、u;for(d=v+1;dM;d+)a(c,d)=a(c,d)-fd*a(c,v);四、程序運行效果及分析這里將通過測試在確定的線程下,對于隨機生成的不同大小的矩陣,串行及OpenMP&MPI的運行時間來分析程序性能。并通過改變線程的數量,在不同情況下多次測量,測試編譯參數對程序性能的影響。4.1、固定線程數時,不同矩陣大小下性能測試當線程數為5時:測試得到的不同矩陣大小下的加速比數據如圖1所示:圖1 根據圖1中所示測得的數據,生成折線圖如下:b當線程數為100時,測得的實驗數據如圖2所示:圖2根據圖2中所示測得實驗數據生成的折線圖如下:結果分析:從以上的結果可以看出在不同的線程下,OpenM
16、P的性能都會隨著矩陣規模的增大而變好,也就是在矩陣規模變大時,OpenMP的加速比變大,雖然在實驗中有出現下降,但總體來說加速比在增大。同時,可以看到在矩陣很小時,加速比幾乎為零,也即此時的OpenMP運行時間比串行時間久,這主要是在矩陣規模很小時,OpenMP多線程減少的計算時間相比為維護這么多線程花費的時間要少很多,所以在數據規模很小時,不應該采用OpenMP編程并行編程。相反,在數據規模很大時,采用OpenMP并行編程模型,將帶來巨大的性能提升。4.2、固定矩陣大小時,不同線程數下的性能測試a當矩陣大小為2000時,測得的數據如圖3所示:圖3根據圖3測得實驗數據,生成的折線圖如下:b當矩
17、陣大小為4000時,測得的數據如圖4所示:圖4根據圖4測得實驗數據,生成的折線圖如下:結果分析:從上面的實驗測試可以看出,在不同的線程數量下,OpenMP運行的加速比不同,同線程數量變大時,OpenMP的加速比并沒有如所期望的一樣變大,相反隨線程數量的增加,OpenMP的加速比變小了。因為OpenMP是基于多線程的編程模型,而我們知道多線程程序性能的提高是基于多CPU同時運行線程,而本次程序測試的主機為4核的,也即可以同時運行4個線程,因此當線程數量增多到超過CPU數量時,多余的線程實際上并沒有得到執行,相反這個時候還需要額外維護這大量的線程,因此性能降低,所以加速比隨線程增多而有所降低。因此
18、,在進行OpenMP并行編程時,我們需要根據所運行的主機的CPU數量合理的設置線程的數量,以獲得最大的加速比。以上是針對OpenMP并行算法與串行算法的性能的比較,下面再簡單對不同進程情況下MPI的LU并行算法與串行算法的性能比較。c. 分別在矩陣大小為3000和4000時測得的實驗數據如下:根據測得的實驗數據,生成的折線圖如下:結果分析:從上面的實驗測試結果,可以看出,在進程為4時,MPI的加速比為最大,而在兩邊變化時,加速比有所下降。也即在進行MPI并行編程時,合理設置進程也是非常重要的,一般也是根據運行主機的CPU的數量來設置,如本次主機的CPU數量為4,所以設置進程數為4,每個CPU分別負責執行一個進程,在進程數量過多時,進程沒有被執行,反而還增加了維護進程的開銷,我們知道這個開銷是很大的。結論:無論是MPI并
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
評論
0/150
提交評論