MPI的缓冲通讯

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) 这种情况 为了确保 安全性 如果不能确保 那么发送方进行其他操作 缓冲区极有可能 之前的没被清空 出现数据混乱 而且这个是 释放缓存是阻塞调用,它一直等到使用该缓存的消息发送完成后才返回,这一调用返回后用户可以重新使用该缓冲区或者将这一缓冲区释放。
最后我们可以自己手动释放缓存

上一篇:Unity编程标准导引-3.1 Component 组件脚本及其基本生命周期


下一篇:Unity编程标准导引-3.2 MonoBehavior 组件父类重构