MPI之MPI_Send&MPI_Recv阻塞接口及参数详解

MPI简介以及阻塞非阻塞代码示例

函数原型:

MPI_Send

int MPI_Send(void *buf, int count, MPI_Datatype datatype, 
int dest, int tag, MPI_Comm comm)
  • buf:指向发送缓冲区的指针;
  • count:发出的消息的数量(例如,整数个数、字节数等);
  • datatype:发出消息的数据类型。MPI 数据类型通常是针对特定的数据结构(如 char、int、float 等)定义的,它仅能在使用相同 MPI_Datatype 的进程间传递数据;
  • dest:目标进程的标识符(MPI_Comm 值)。该参数用于指定消息的目标进程,它必须等于 MPI_Init 时返回的进程 ID,或者是调用 MPI_Comm_rank 函数返回的值。
  • tag:消息标记,用于识别消息。每个消息都有一个唯一的标记,接收方可以使用它来过滤出要接收的消息,如果数据发送时指定的tag和数据接受时指定的tag不一致,数据将无法接收
  • comm:MPI 通信器,用于指定通信域。该参数定义了进程组,这些进程可以相互通信;

返回值:函数执行成功,返回 MPI_SUCCESS。如果发生错误,则返回相应的错误码。

MPI_Recv

int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, 
int tag, MPI_Comm comm, MPI_Status *status)
  • buf:接收缓冲区的指针,用于接收从另一个进程中到来的数据。
  • count:接收数据的数量(例如,整数个数、字节数等);
  • datatype:接收数据的数据类型。MPI 数据类型通常是针对特定的数据结构(如 char、int、float 等)定义的,它仅能在使用相同 MPI_Datatype 的进程间传递数据;
  • source:发送消息的源进程的标识符。该参数用于指定发送消息的源进程,它必须等于 MPI_Init 时返回的进程 ID,或者是调用 MPI_Comm_rank 函数返回的值。如果该值等于 MPI_ANY_SOURCE,则表示从任何进程接收消息;
  • tag:消息标记,用于识别消息。每个消息都有一个唯一的标记,接收方可以使用它来过滤出要接收的消息。如果该值等于 MPI_ANY_TAG,则表示接收任何标记的消息;
  • comm:MPI 通信器,用于指定通信域。该参数定义了进程组,这些进程可以相互通信。
  • status:包含接收到的消息的状态信息,包括消息的源、标记和错误信息等。如果不需要这些状态信息,可以传递 MPI_STATUS_IGNORE。

返回值:函数执行成功,返回 MPI_SUCCESS。如果发生错误,则返回相应的错误码。
MPI_Recv 函数是 MPI 标准中的一个阻塞函数,它将一直阻塞直到接收到来自指定源和标记的消息。

代码示例:

//0号进程给1号进程发送数据
#include "mpi.h"
#include <unistd.h>
#include <iostream>


int main(int argc, char *argv[])
{
    int err = MPI_Init(&argc,&argv);
    int rank,size;
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    if(0 == rank)
    {
        int sendNum = 99;
        //这里指定消息的标签为0   目标进程的标识符为1
        int tag = 0;
        int dest = 1;
        MPI_Send(&sendNum, 1 ,MPI_INT ,dest , tag , MPI_COMM_WORLD);
    }
    else
    {
        int recvNum = 0;
        //这里指定接收的消息的标签为0   消息源的进程的标识符为1
        //如果这里tag 不等于0,将无法接收到发送进程来的消息
        //如果指定tag为MPI_ANY_TAG,将可以接受源进程发送的任意标签的消息
        //
        int tag = 0;
        int source = 1;
        MPI_Status status;
        std::cout << "before recv , recv num = " << recvNum << std::endl;
        MPI_Recv(&recvNum, 1 ,MPI_INT , source, tag, MPI_COMM_WORLD, &status);
        std::cout << "before recv , recv num = " << recvNum << std::endl;
    }
    
    err = MPI_Finalize();
    return 0;
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`MPI_Sendrecv` 函数是 MPI 库中的一个消息传递函数,它可以在一个函数调用中完成发送和接收操作,因此可以避免死锁等问题。 `MPI_Sendrecv` 函数的原型如下: ``` int MPI_Sendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, int dest, int sendtag, void *recvbuf, int recvcount, MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm, MPI_Status *status) ``` 该函数有以下参数: - `sendbuf`:发送缓冲区的指针。 - `sendcount`:要发送的数据的数量。 - `sendtype`:要发送的数据的类型。 - `dest`:目标进程的标识符。 - `sendtag`:发送消息的标签。 - `recvbuf`:接收缓冲区的指针。 - `recvcount`:要接收的数据的数量。 - `recvtype`:要接收的数据的类型。 - `source`:发送消息的进程的标识符。 - `recvtag`:接收消息的标签。 - `comm`:通信子。 - `status`:接收消息的状态。 该函数的作用是将 `sendbuf` 中的 `sendcount` 个数据按照 `sendtype` 类型发送给进程 `dest`,并从进程 `source` 接收数据到 `recvbuf` 中,数据类型为 `recvtype`,数量为 `recvcount`,接收消息的标签为 `recvtag`,发送消息的标签为 `sendtag`,通信子为 `comm`。 需要注意的是,`MPI_Sendrecv` 函数是一个阻塞函数,也就是说,它会一直等待直到发送和接收都完成。在函数返回后,可以通过 `status` 参数来获取接收消息的状态。 下面是一个简单的例子: ```c #include <mpi.h> #include <stdio.h> int main(int argc, char** argv) { int rank, size; int sendbuf, recvbuf; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == 0) { sendbuf = 123; MPI_Sendrecv(&sendbuf, 1, MPI_INT, 1, 0, &recvbuf, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, &status); printf("Process %d sent %d and received %d\n", rank, sendbuf, recvbuf); } else if (rank == 1) { sendbuf = 456; MPI_Sendrecv(&sendbuf, 1, MPI_INT, 0, 1, &recvbuf, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); printf("Process %d sent %d and received %d\n", rank, sendbuf, recvbuf); } MPI_Finalize(); return 0; } ``` 上面的代码中,进程 0 向进程 1 发送数据 123,同时接收来自进程 1 的数据。进程 1 向进程 0 发送数据 456,同时接收来自进程 0 的数据。最终输出结果为: ``` Process 0 sent 123 and received 456 Process 1 sent 456 and received 123 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值