MPI的缓冲通讯 我们可以通过自定义缓冲区 然后进行通讯操作 但是这种方式类似标准通讯方式 但是却还是有区别 当我们的消息大小大于缓冲区时候就会报错 但是标准通讯 不会 他会阻塞等到接受动作开启时候进行发送 为了更加的安全 我们可以采缓冲通讯 这样可以保证通讯缓冲区 可以手动计算 通过MPI_Pack_size 最后通过n*MPI_BSEND_OVERHEAD+计算出来的消息缓冲区上界限 通过MPI_Buffer_attach进行装载 缓冲区 当我们通信的时候会出现很多情况 我就不一一例举了 这种情况可以忽略因为那么多的情况 其实 我们只要保证安全性就可以了 就是通过同步的方式 而且也可以避免缓冲区报错 下面举个例子
#include"mpi.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc,char**argv)
{
int procnum,rank;
MPI_Comm comm=MPI_COMM_WORLD;
MPI_Init(&argc,&argv);
MPI_Comm_rank(comm,&rank);
MPI_Comm_size(comm,&procnum);
int src=0,des=1;
char* buf;
int s1,s2;
int buffsize;
char msg1[112],msg2[7],rmsg1[12],rmsg2[12];
MPI_Pack_size(17,MPI_CHAR,comm,&s1);
MPI_Pack_size(7,MPI_CHAR,comm,&s2);
buffsize=2*MPI_BSEND_OVERHEAD+s1+s2;
buf=(char*)malloc(buffsize);
MPI_Buffer_attach(buf,buffsize);
char arr[111]="12312312312312312312312312312311";
strncpy(msg1,arr,sizeof(arr)+1);
strncpy(msg2,"asdasd",7);
if(rank==src)
{
printf("%d process---\n",rank);
MPI_Bsend(msg1,100,MPI_CHAR,des,1,comm);
MPI_Bsend(msg2,7,MPI_CHAR,des,1,comm);
MPI_Buffer_detach(&buf,&buffsize);
MPI_Barrier(comm);
}
MPI_Status status;
if(rank==des)
{
MPI_Barrier(comm);
printf("%d process---\n",rank);
MPI_Recv((void*)rmsg1,100,MPI_CHAR,src,1,MPI_COMM_WORLD,&status);
if(strcmp(rmsg1,msg1)==0)
{
fprintf(stdout,"recv1==%s\n",msg1);
}
else
{
fprintf(stderr,"error recv1:%s\t and msg1:%s\n",rmsg1,msg1);
}
MPI_Recv((void*)rmsg2,100,MPI_CHAR,src,1,MPI_COMM_WORLD,&status);
if(strcmp(rmsg2,msg2)==0)
{
fprintf(stdout,"recv2==%s\n",msg2);
}
MPI_Buffer_detach(&buf,&buffsize);
}
free(buf);
MPI_Finalize();
return 0;
}
很明显 当我们程序发送 方MPI_Buffer _detach 时候是清空缓冲区 相当于fflush(stdout) 这种情况 为了确保 安全性 如果不能确保 那么发送方进行其他操作 缓冲区极有可能 之前的没被清空 出现数据混乱 而且这个是 释放缓存是阻塞调用,它一直等到使用该缓存的消息发送完成后才返回,这一调用返回后用户可以重新使用该缓冲区或者将这一缓冲区释放。
最后我们可以自己手动释放缓存