
?MPI_Send和MPI_Recv實(shí)現(xiàn)簡(jiǎn)單集群通信函數(shù)
本?博客總結(jié)?我《并?計(jì)算》MPI實(shí)驗(yàn)
在這?我?阻塞式消息傳遞函數(shù)MPI_Send、MPI_Recv和?阻塞式消息發(fā)送函數(shù)MPI_Ind實(shí)現(xiàn)了三個(gè)簡(jiǎn)單的集群通信函數(shù):
MPI_Bcast?播函數(shù)
MPI_Gather收集函數(shù)
MPI_Scatter散播函數(shù)
_Bcast?播函數(shù)
(1)原型簡(jiǎn)介
MPI_Bcast實(shí)現(xiàn)將root節(jié)點(diǎn)的address地址處長(zhǎng)度為count的datatype類型的數(shù)據(jù)發(fā)送給其他節(jié)點(diǎn)。其他節(jié)點(diǎn)接收這塊數(shù)據(jù)的內(nèi)存空間也是
?塊以address為起始地址,長(zhǎng)度為count*MPI_Type_size(datatype)的內(nèi)存區(qū)域。
(2)實(shí)現(xiàn)
實(shí)現(xiàn)邏輯為:
若節(jié)點(diǎn)為root則接收來(lái)?所有其他除root以外的節(jié)點(diǎn)的消息,否則向root節(jié)點(diǎn)發(fā)送?條消息。
?播?較簡(jiǎn)單,直接看代碼:
_Gather收集函數(shù)
(1)原型簡(jiǎn)介
MPI_Gather實(shí)現(xiàn)將所有節(jié)點(diǎn)的ndAddress為起始地址、長(zhǎng)度為ndCount的ndDatatype類型數(shù)據(jù),發(fā)送到root節(jié)點(diǎn)以
recvAddress為起始地址、長(zhǎng)度為MPI_Comm_size*recvCount*MPI_Type_size(recvDatatype)的內(nèi)存區(qū)域。并且。是按照進(jìn)程序號(hào)
rank依次排列所有節(jié)點(diǎn)發(fā)送的數(shù)據(jù),即序號(hào)為i的節(jié)點(diǎn)發(fā)送給root節(jié)點(diǎn)的數(shù)據(jù)接收內(nèi)存的起始地址是recvAddress+i*recvCount*
MPI_Type_size(recvDatatype)。
voidMPI_Bcast(void*address,intcount,MPI_Datatypedatatype,introot,MPI_Commcomm);
voidMy_Bcast(void*ndAddress,intcount,MPI_Datatypedatatype,introot,MPI_Commcomm){
intrank,size,i;
MPI_Statusstatus;
inttag=100;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
if(rank==root){
for(i=0;i
if(i!=root){
MPI_Send(ndAddress,count,datatype,i,tag,comm);
}
}
}el{
MPI_Recv(ndAddress,count,datatype,root,tag,comm,&status);
}
}
voidMPI_Gather(void*ndAddress,intndCount,MPI_DatatypendDatatype,void*recvAddress,intrecvCount,MPI_DatatyperecvDatatype,
因?yàn)檫@次是初學(xué)并?計(jì)算第?次?MPI編程,這?有個(gè)疑問(wèn):為什么不強(qiáng)制要求recvDatatype==ndDatatype&&recvCount==
ndCount?如果不統(tǒng)?不會(huì)造成內(nèi)存泄漏?我測(cè)試recvCount!=ndCount雖然沒(méi)有SegmentFault,但結(jié)果全亂了
(2)實(shí)現(xiàn)
我下?的實(shí)現(xiàn)沒(méi)有考慮datatype和count不?致的問(wèn)題,均默認(rèn)相同!
實(shí)現(xiàn)邏輯為:
當(dāng)前節(jié)點(diǎn)向root節(jié)點(diǎn)發(fā)送?條消息,如果當(dāng)前節(jié)點(diǎn)是root節(jié)點(diǎn)則枚舉接收來(lái)?所有節(jié)點(diǎn)的消息。
注意:這時(shí)root節(jié)點(diǎn)需要向它??發(fā)送?條消息,如果?標(biāo)準(zhǔn)通信模式(MPI管理消息緩存的通信模式,MPI_Send和MPI_Recv均屬于這
種模式,詳見(jiàn)陳國(guó)良?師《并?計(jì)算》P418頁(yè)通信模式介紹或Google),由于MPI_Send和MPI_Recv是阻塞式通信且它們共?同?緩沖
區(qū),那么同?節(jié)點(diǎn)即調(diào)?MPI_Send?調(diào)?MPI_Recv將會(huì)由于緩沖區(qū)資源沖突造成死鎖!
解決?法是??阻塞的發(fā)送函數(shù)MPI_Ind
代碼如下:
代碼中需要注意的是root節(jié)點(diǎn)每次MPI_Recv起始地址的計(jì)算公式,需要調(diào)?MPI_Type_size(recvDatatype,&tsize)獲取datatype類型的
字節(jié)長(zhǎng)度。
_Scatter散播函數(shù)
(1)原型簡(jiǎn)介
MPI_Scatter和MPI_Gather互為逆向函數(shù),MPI_Gather搜集所有節(jié)點(diǎn)的數(shù)據(jù)依次拼接存放在root節(jié)點(diǎn)中?塊類似于數(shù)組的連續(xù)區(qū)域當(dāng)
中,?MPI_Scatter相當(dāng)于把root節(jié)點(diǎn)中?塊類似于數(shù)組的連續(xù)區(qū)域分割成size塊依次分發(fā)給所有節(jié)點(diǎn)。其參數(shù)列表和MPI_Gather相同,
不再解釋。
(2)實(shí)現(xiàn)
我下?的實(shí)現(xiàn)沒(méi)有考慮datatype和count不?致的問(wèn)題,均默認(rèn)相同!
實(shí)現(xiàn)邏輯為:
voidMy_Gather(void*ndAddress,intndCount,MPI_DatatypendDatatype,void*recvAddress,intrecvCount,MPI_DatatyperecvDatatype,int
intrank,size,i;
inttag=101;
MPI_Statusstatus;
MPI_Requestrequest;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Ind(ndAddress,ndCount,ndDatatype,root,tag,comm,&request);
if(rank==root){
inttsize;
MPI_Type_size(recvDatatype,&tsize);
for(i=0;i
MPI_Recv(recvAddress+i*recvCount*tsize,recvCount,recvDatatype,i,tag,comm,&status);
}
}
}
voidMPI_Scatter(void*ndAddress,intndCount,MPI_DatatypendDatatype,void*recvAddress,intrecvCount,MPI_DatatyperecvDatatype,
判斷該節(jié)點(diǎn)是否是root節(jié)點(diǎn),若是則向所有節(jié)點(diǎn)發(fā)送?條消息(?阻塞MPI_Ind)。然后該節(jié)點(diǎn)接收?條來(lái)?于root的消息。
和之前的?樣,涉及到同?節(jié)點(diǎn)之間的消息傳遞,需要??阻塞通信。我嘗試過(guò)先?阻塞Recv再阻塞Send,運(yùn)?結(jié)果不對(duì),后來(lái)思考確實(shí)
有問(wèn)題:root節(jié)點(diǎn)?阻塞Recv若先于其他?誒但阻塞Send執(zhí)?,這個(gè)Recv什么消息也接收不到就結(jié)束了(?阻塞Recv查看?次緩沖區(qū)不
管有沒(méi)有消息均結(jié)束,有則返回消息沒(méi)有則返回空消息,詳見(jiàn)其定義)。
代碼如下,仍需注意root節(jié)點(diǎn)發(fā)送數(shù)據(jù)的起始地址:
voidMy_Scatter(void*ndAddress,intndCount,MPI_DatatypendDatatype,void*recvAddress,intrecvCount,MPI_DatatyperecvDatatype,int
intrank,size,i;
inttag=102;
MPI_Requestrequest;
MPI_Statusstatus;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
if(rank==root){
inttsize;
MPI_Type_size(ndDatatype,&tsize);
for(i=0;i
MPI_Ind(ndAddress+i*ndCount*tsize,ndCount,ndDatatype,i,tag,comm,&request);
}
}
MPI_Recv(recvAddress,recvCount,recvDatatype,root,tag,comm,&status);
}
本文發(fā)布于:2023-03-14 04:51:54,感謝您對(duì)本站的認(rèn)可!
本文鏈接:http://www.newhan.cn/zhishi/a/167874071429131.html
版權(quán)聲明:本站內(nèi)容均來(lái)自互聯(lián)網(wǎng),僅供演示用,請(qǐng)勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)刪除。
本文word下載地址:bcast.doc
本文 PDF 下載地址:bcast.pdf
| 留言與評(píng)論(共有 0 條評(píng)論) |