高性能并行计算-非阻塞式点对点通信



/*MPI进程间点对点非阻塞通信*/
#include "mpi.h" /*MPI头函数,提供了MPI函数和数据类型定义*/
#include <stdio.h>

int main(int argc, char** argv)
{
    int rank;   //进程标识
    int size;   //进程总数
    int senddata;   //待发送数据缓存
    int recvdata;   //待接收数据缓存
    int flag_s, flag_r; //通信状态标志,0为通信未完成,1位通信已完成
    MPI_Status status_s, status_r;  //status object (Status)
    MPI_Request handle_s, handle_r; //MPI request (handle)

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    /*初始化数据*/
    senddata = rank + 1;
    recvdata = 0;
    flag_s = 0;
    flag_r = 0;

    if(rank == 0){
        /*----------------------------MPI_Isend详解--------------------------*/

        //功能:
        //  进行点对点非阻塞进程通信(消息发送)
        //参数:
        //int MPI_Isend(const void *buf, int count, MPI_Datatype datatype
        //                    , int dest, int tag,MPI_Comm comm, MPI_Request *request)
        //  MPI_Isend(数据发送缓存地址,数据个数,数据类型,目标进程标识,消息标志
        //              ,通信域,消息发送请求句柄地址)
        MPI_Isend(&senddata, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &handle_s);  //向1号进程发送消息

        /*----------------------------MPI_Irecv详解--------------------------*/
        //功能:
        //  进行点对点非阻塞进程通信(消息接收)
        //参数:
        //int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source
        //                ,int tag, MPI_Comm comm, MPI_Request *request)
        //  MPI_Irecv(数据接收缓存地址,数据个数,数据类型,数据来源进程标识
        //               ,消息标志,通信域,消息接收请求句柄地址)
        MPI_Irecv(&recvdata, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &handle_r);  //接收1号进程发来的消息

        //flag=0;//采用循环等待的方法等待非阻塞发送的完成
        while (flag_s == 0) {
            /*-------------------------MPI_Test详解-------------------------*/
            //功能:
            //  1.A call to MPI_TEST returns flag = true if the operation 
            //  identified by request is complete
            //  如果当前检测的请求完成的话,返回通信状态标志位为true
            //  2.One is allowed to call MPI_TEST with a null or inactive
            //  request argument. In such a case the operation returns with
            //  flag = true and empty status.
            //  如果检测一个空的或未激活的通信请求,则标志位返回true,检测的
            //  通信状态信息返回空
            //  3.The functions MPI_WAIT and MPI_TEST can be used to complete
            //  both sends and receives
            //  MPI_WAIT和MPI_TEST即可用于检测消息发送状态也可用于消息接收状态
            //参数:
            //  MPI_Test(请求句柄,消息标志,检测的当前请求[发送或接收]的通信状态)
            MPI_Test(&handle_s, &flag_s, &status_s);    //监听消息发送状态,发送完成,返回flag_s为true,否则为false
        }
        //采用循环等待的方法等待非阻塞接收的完成
        while (flag_r == 0) {
            MPI_Test(&handle_r, &flag_r, &status_r);    //监听消息接收状态,接收完成,返回flag_s为true,否则为false
        }
        printf("rank %d send ok,send = %d\n", rank, senddata);
        printf("rank %d recv ok,recv = %d\n", rank, recvdata);
    }
    else if(rank == 1){
            MPI_Isend(&senddata, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &handle_s);  //向0号进程发送消息
            MPI_Irecv (&recvdata, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &handle_r); //接收0号进程发来的消息
            //采用循环等待的方法等待非阻塞发送的完成
            while(flag_s == 0){
                MPI_Test(&handle_s, &flag_s, &status_s);    //监听消息发送状态,发送完成,返回flag_s为true,否则为false
            }
            //采用循环等待的方法等待非阻塞接收的完成
            while(flag_r == 0){
                MPI_Test(&handle_r, &flag_r, &status_r);    //监听消息接收状态,接收完成,返回flag_s为true,否则为false
            }
            printf("rank 1 send ok,send = %d\n",senddata);

            printf("rank 1 recv ok,recv = %d\n",recvdata);
    }
    MPI_Finalize(); /*MPI的结束函数*/
    return (0);
}

运行结果

等待、检测一个通信请求的完成

MPI_Wait和MPI_Test

MPI_Wait阻塞等待通信函数完成后返回;MPI_Test检测某通信,不论其是否完成,都立刻返回。如果通信完成,则flag=true
当等待或检测的通信完成时,通信请求request被设置成MPI_REQUEST_NULL
考察接收请求,status返回与MPI_Recv一样;发送请求,则不确定
MPI_Test返回时,当flag=false, status不被赋值

等待、检测一组通信请求中某一个的完成

等待、检测一组通信请求中某的全部完成

posted @   economies  阅读(235)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示