湖南大学SCCI并行计算组-MPI并行编程教程-02

本文深入探讨了MPI(Message Passing Interface)中的点对点通信机制,详细解析了MPI_Send和MPI_Recv函数的参数与作用机理。通过具体代码示例,展示了如何在并行环境中实现进程间的数据交换。

《并行程序设计导论》第三章:

湖南大学SCCI并行计算组
MPI并行编程教程02

三、MPI实现


3.点对点通信

(1)发送: MPI_Send函数:

函数原型:

int MPI_Send(
        void*           msg_buf_p,
        int             msg_size,
        MPI_Datatype    msg_type,
        int             dest,
        int             tag,
        MPI_Comm        communicator){...}


参数解释:
  ①void* msg_buf_p:
  消息的地址。
  ②int msg_size:
  消息的大小(字节数)。
  ③MPI_Datatyoe msg_type:
  MPI自己的数据类型。
  ④int dest:
  发送消息的目的地,也就是接收进程的进程号。
  ⑤int tag:
  标签,用于区分多个消息。随意设置(如0、1、2…),但MPI_Send与MPI_Recv的tag值相等接收成功。
  ⑥MPI_Comm communicator:
  通信子名字。
  ⑦返回值:
  错误码。

函数作用:
  当前调用此函数的进程,将msg_buf_p指向的内存中msg_size大小的msg_type类型的消息,并打上tag标签后,发给名叫communicator通信子中序号为dest的进程。



(2)接收: MPI_Recv函数:

函数原型:

int MPI_Recv(
        void*           msg_buf_p,
        int             buf_size,
        MPI_Datatype    buf_type,
        int             source,
        int             tag,
        MPI_Comm        communicator,
        MPI_Status*     status_p){...}


参数解释:
  ①void* msg_buf_p:
  接收到的消息要存放的地址。
  ②int buf_size:
  消息存放区的大小(字节数)。
  ③MPI_Datatype buf_type:
  消息存放区的数据类型。
  ④int source:
  接收消息的来源地,也就是发送这个消息的进程的进程号。注意,只有在MPI_Recv函数中才存在一个特殊的MPI常量:MPI_ANY_SOURCE意为可以接收任意来源进程的信息。
  ⑤int tag:
  标签,用于区分多个消息。随意设置(如0、1、2…),但MPI_Send与MPI_Recv的tag值相等接收成功。注意,只有在MPI_Recv函数中才存在一个特殊的MPI常量:MPI_ANY_TAG意为可以接收任意标签值的信息。
  ⑥MPI_Comm communicator:
  通信子名字。
  ⑦MPI_Status* status_p
  大部分情况下,我们并不使用这个参数,通常用特殊的MPI常量MPI_STATUS_IGNORE填写参数。更深一步:该参数实际上存放有来源地相关的信息,可以用MPI_Get_count函数来得到。
  ⑧返回值:
  错误码。

函数作用:
  当前调用此函数的进程接收来自名为communicator通信子中进程号为source的进程发来的消息,并将此消息存放在msg_buf_P指向的buf_type类型且大小为buf_size的内存区域中。

(3)MPI_Datatype类型

MPI_Datatype

(4)send与recv的作用机理
  ①MPI_Recv是阻塞型(挂起型),必须要有与之配对的MPI_Send函数在MPI缓存中,MPI_Recv才会激活工作。
  ②更进一步:同一组收发配对进程调用MPI_Send函数与MPI_recv有严格的顺序关系,如:进程1先Send一个A消息到进程2,再Send一个B消息到进程2,那么进程2一定是先接收A再接收B,无论进程2的MPI_Recv的顺序如何。
  ③更进一步:MPI_Send函数,是将消息传递到MPI缓存中便返回,而MPI_Recv函数是进程成功接收到消息后才返回。


(5)练习
请将下面的代码补充完整


/*介绍:
 *由0号进程输出:进程0中的a的值与进程1中的a的值与进程2中的a的值的和
*/

/*----头文件------*/
#include <stdio.h>
#include <?>//请补充:MPI头文件
/*---------------*/

/*---建立全局变量---*/
MPI_? comm;//请补充:通信子的MPI类型
int comm_sz;
int my_rank;
/*-------------------*/

int main(int argc,int* argv[]){
    MPI_//请补充:MPI初始化
    comm = ?;//请补充:通信子名
    MPI_//请补充:获得通信子大小返回给comm_sz
    MPI_//请补充:获得当前进程号返回给my_rank
    
    int a = 5;
    int b = 0;
    int c = 0;
    int sum = 0;
    if(my_rank==1){
        a = 7;
        MPI_Send(&a,1,MPI_INT,0,0,comm);
    }
    if(my_rank==2){
        a = 9;
        MPI_Send();//请补充:将a的值发送给0号进程,tag值为1
    }
    if(my_rank==0){
        MPI_Recv();//请补充:接收来自1号进程的消息并存入b中
        MPI_Recv(&c,1,MPI_INT,2,1,comm,MPI_STATUS_IGNORE);
        sum = a+b+c;
        printf("I am proc%d in %d,proc0a+proc1a+proc2a=%d\n",my_rank,comm_sz,sum);
    }
    MPI_Finalize();
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值