1.實驗?zāi)康?/h2>
1.1.通過MPI實現(xiàn)通用矩陣乘法
熟練掌握MPI編程方法,并將通用矩陣乘法轉(zhuǎn)為MPI并行實現(xiàn),進(jìn)一步加深MPI的使用與理解。
1.2.基于MPI的通用矩陣乘法優(yōu)化
進(jìn)一步熟悉MPI矩陣乘法的實現(xiàn),學(xué)習(xí)MPI點對點通信與集合通信的異同點和各自的優(yōu)缺點,學(xué)會比較二者的性能以及各自使用的情形。
1.3.改造實驗1成矩陣乘法庫函數(shù)
學(xué)習(xí)如何將自己編寫的代碼改造為標(biāo)準(zhǔn)庫函數(shù),供其他程序調(diào)用。
理解動態(tài)鏈接的過程。
2.實驗過程和核心代碼
2.1.通過MPI實現(xiàn)通用矩陣乘法
2.1.1.問題描述
通過 MPI 實現(xiàn)通用矩陣乘法(實驗1)的并行版本,MPI并行進(jìn)程(rank size)從 1 增加至 8,矩陣規(guī)模從 512 增加至 2048.
問題描述:隨機生成 MN 和NK 的兩個矩陣 A,B,對這兩個矩陣做乘法得到矩陣 C.
輸入:M , N, K 三個整數(shù)(512 ~2048)
輸出:A,B,C 三個矩陣以及矩陣計算的時間
2.1.2.實現(xiàn)過程
這里可以選擇點對點通信或者集合通信的方式實現(xiàn),這里選擇點對點方式,使用MPI_Send、MPI_Recv函數(shù)進(jìn)行進(jìn)程通信。
思想:
最簡單的實現(xiàn),按行并行:
主進(jìn)程不參與計算,只負(fù)責(zé)分發(fā)和收集數(shù)據(jù)。在主進(jìn)程中,A根據(jù)處理器數(shù)按行劃分為大致相等的N部分,然后將部分的A和全部的B傳遞給子進(jìn)程。子進(jìn)程計算部分乘法并返回結(jié)果,主進(jìn)程收集并整合報告結(jié)果。使用最簡單的Send和Recv進(jìn)行通信。
2.1.3.核心代碼
①矩陣生成
void Gen_Matrix(int m,int n,int k){
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
A[i][j] = rand()%5;
}
}
for(int i=0;i<n;i++){
for(int j=0;j<k;j++){
B[i][j] = rand()%5;
}
}
}
②MPI初始化
③獲得進(jìn)程數(shù)(通過bash)
④獲得時間
⑤主處理器
這里主處理器通過Send傳遞給每一個處理器n/pnum行A、與整個的B,接著接受所有子處理器返回的結(jié)果進(jìn)行拼接。
⑥子處理器
這里子處理器需要相應(yīng)的接受Recv主處理器Send的過來的A部分行與整個的B,接著進(jìn)行計算,即matMulti函數(shù),最后Send回結(jié)果。
⑦矩陣乘法
這里就是簡單的使用樸素計算方法,為了方便,直接將結(jié)果存在了部分結(jié)果矩陣返回。
2.2.通用矩陣乘法優(yōu)化
2.2.1.問題描述
分別采用 MPI 點對點通信和 MPI 集合通信實現(xiàn)矩陣乘法中的進(jìn)程之間通信,并比較兩種實現(xiàn)方式的性能。
上面已經(jīng)采用點對點通信的方式進(jìn)行了實現(xiàn),接下來針對集合通信來進(jìn)行實驗。
2.2.2.實現(xiàn)過程
這里分發(fā)A時,是將A平均的分配給了各個進(jìn)程,使用Scatter分發(fā)比較何時,而B要完整的分發(fā)給所有處理器,所以使用Broadcast通信更為方便,收集計算結(jié)果使用Gather。
廣播是最簡單但也是最有用的集體操作之一。
改用Scatter分配數(shù)據(jù)后,每個進(jìn)程分配的部分矩陣具有完全相等的規(guī)模。因此。記comm_sz為進(jìn)程數(shù),矩陣的維度需要是comm_sz的倍數(shù)。我們將矩陣的維度擴展到comm_sz的倍數(shù),多余的部分用0填充,保證正確性。
改用Scatter分配數(shù)據(jù)后,計算任務(wù)平均地分配給每一個進(jìn)程,所以主進(jìn)程不僅要分發(fā)收集結(jié)果,也要參與計算。如果分發(fā)的行數(shù)不夠,就不能保證結(jié)果正確;如果分發(fā)的行數(shù)超出,就會出現(xiàn)很多不同類型的內(nèi)存錯誤(大多都源于free時內(nèi)存泄漏等原因)。
2.2.3.核心代碼
①給A、B矩陣賦初值
這里必須要平均分配給各個處理器,因此有必要在不夠分配時擴大矩陣,就需要在無數(shù)據(jù)的位置補零。
②獲取矩陣大小,這里需要假設(shè)矩陣大小相同(通過bash)
后續(xù)處理,將真實矩陣大小擴展到處理器個數(shù)的倍數(shù)。
③MPI初始化
同上第一部分;
④主線程
主線程額外進(jìn)行初始化矩陣以及計算并輸出時間的工作
使用Scatter平均分發(fā)A的行,Bcast分發(fā)B。
使用Gather收集結(jié)果。
⑤所有處理器計算
MatMulti函數(shù)與上面實驗相同。
2.3.改造實驗1成矩陣乘法庫函數(shù)
2.3.1.問題描述
將Lab1 的矩陣乘法改造為一個標(biāo)準(zhǔn)的庫函數(shù) matrix_multiply(函數(shù)實現(xiàn)文件和函數(shù)頭文件),輸入?yún)?shù)為三個完整定義矩陣(A,B,C),定義方式?jīng)]有具體要求,可以是二維矩陣,也可以是 struct 等。在 Linux 系統(tǒng)中將此函數(shù)編譯為.so 文件,由其他程序調(diào)用。
2.3.2.實驗過程
通常情況下,對函數(shù)庫的鏈接是放在編譯時期(compile)完成的。所有相關(guān)的對象文件(object file)與牽涉到的函數(shù)庫(library)被鏈接合成一個可執(zhí)行文件(executable file)。程序在運行時,與函數(shù)庫再無關(guān)系,因為所有需要的函數(shù)已拷貝到自己門下。所以這些函數(shù)庫被稱為靜態(tài)庫(static libaray),通常文件名為“l(fā)ibxxx.a”的形式。
由于動態(tài)鏈接庫函數(shù)的共享特性,它們不會被拷貝到可執(zhí)行文件中。在編譯的時候,編譯器只會做一些函數(shù)名之類的檢查。在程序運行的時候,被調(diào)用的動態(tài)鏈接庫函數(shù)被安置在內(nèi)存的某個地方,所有調(diào)用它的程序?qū)⒅赶蜻@個代碼段。因此,這些代碼必須使用相對地址,而不是絕對地址。在編譯的時候,我們需要告訴編譯器,這些對象文件是用來做動態(tài)鏈接庫的,所以要用地址無關(guān)代碼(Position Independent Code (PIC))。
對gcc編譯器,只需添加上 -fPIC 標(biāo)簽,如:=
gcc -fPIC -c file1.c
gcc -fPIC -c file2.c
gcc -shared libxxx.so file1.o file2.o
注意到最后一行,-shared 標(biāo)簽告訴編譯器這是要建立動態(tài)鏈接庫。這與靜態(tài)鏈接庫的建立很不一樣,后者用的是 ar 命令。也注意到,動態(tài)鏈接庫的名字形式為 “l(fā)ibxxx.so” 后綴名為 “.so”
2.3.3.核心代碼
①Mat_mul.h頭文件
這里自定義矩陣,包括行、列、矩陣體,同時聲明需要的函數(shù)。
②Mat_mul.c頭文件
Malloc_matrix函數(shù)用于根據(jù)矩陣rows\cols分配矩陣并進(jìn)行初始化。
Free_matrix函數(shù)用于釋放相應(yīng)空間。
Mul_matrix函數(shù)是核心計算函數(shù),會首先檢查是否滿足乘法條件。
3.實驗結(jié)果
3.1.通過MPI實現(xiàn)通用矩陣乘法
編譯得到相應(yīng)的MPI程序;
執(zhí)行得到2048大小的矩陣使用2個處理器時間消耗為186s
執(zhí)行得到2048大小的矩陣使用4個處理器時間消耗為75s
結(jié)果可以看出在處理器足夠的情況下,增加處理器數(shù)目可以大大提高運算速度,符合預(yù)期。
3.2.基于MPI的通用矩陣乘法優(yōu)化
編譯程序:
執(zhí)行得到2048大小的矩陣使用4個處理器時間消耗為87s,2048大小的矩陣使用2個處理器時間消耗為140s。
結(jié)果可以看出在處理器足夠的情況下,增加處理器數(shù)目可以大大提高運算速度,符合預(yù)期。
3.3.改造實驗1成矩陣乘法庫函數(shù)
編譯為.so文件
改變當(dāng)前動態(tài)庫路徑為當(dāng)前目錄
編寫的測試文件;
測試結(jié)果:
查看鏈接:
自己的.so文件成功鏈接。文章來源:http://www.zghlxwxcb.cn/news/detail-779705.html
4.實驗感想
本次實驗是高性能實驗的核心,主要是使用MPI進(jìn)行矩陣乘法的實現(xiàn)與優(yōu)化,總體來說并不是很難,需要掌握點對點與集群通信兩種方式的MPI。
其中還有很多可以優(yōu)化的點,比如傳遞給處理器的整個的B是沒有必要的,我們可以簡單的對B矩陣進(jìn)行轉(zhuǎn)置,接著把與傳遞A相同的幾行傳遞給處理器即可,可以大大減少通信量。文章來源地址http://www.zghlxwxcb.cn/news/detail-779705.html
到了這里,關(guān)于高性能計算實驗——矩陣乘法基于MPI的并行實現(xiàn)及優(yōu)化的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!