MPI点对点标准通信

MPI点对点标准通信

1.先来熟悉一下MPI运行环境以及进程分配

/*
 * MPI hello
 * MPI_COMM_WORLD
 * MPI_Init & MPI_Finalize & MPI_Comm_size & MPI_Comm_rank
 *
 */

#include<stdio.h>
#include<mpi.h>

int main()
{
    // 用来标记当前进程号
    int my_rank;
    // 用来表示通信进程集和总数
    int comm_size;
    // 初始化mpi执行环境
    MPI_Init(NULL,NULL);
    // MPI_COMM_WORLD为进程集和,由MPI_Init()函数创建,它的大小由启动参数决定
    // 如mpiexec -n 10 ./exec,则通信集和的大小为为10
    // 获取当前进程号
    MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
    // 获取启动进程总数
    MPI_Comm_size(MPI_COMM_WORLD,&comm_size);

    if(my_rank==0)
        printf("总共有%d个进程\n",comm_size);
    printf("你好,我是%d号进程。\n",my_rank);

    // 释放mpi运行环境所占的资源
    MPI_Finalize();
    return 0;
}

2.MPI点对点标准阻塞通信

/*
 * MPI点对点通信
 * 标准模式,阻塞式
 * MPI_Send & MPI_Recv
 */

#include<stdio.h>
#include<mpi.h>

int main()
{
    int my_rank;
    int comm_size;
    MPI_Init(NULL,NULL);
    MPI_Comm_size(MPI_COMM_WORLD,&comm_size);
    MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);

    // 关键函数
    // MPI_Send(要发送消息的地址,消息的大小,消息的类型,指定接受的进程号,消息的标志,通信集和)
    // MPI_Recv(用来保存消息的地址,消息的大小,消息的类型,发送消息的进程号,消息的标志,通信集和,状态信息)

    // 其它进程向0号进程发送消息
    if(my_rank!=0)
    {
        // 发送消息给0号进程,消息内容为当前进程号
        MPI_Send(&my_rank,1,MPI_INT,0,0,MPI_COMM_WORLD);
    }
    // 0号进程接收消息
    else
    {
        // 若启动了一个进程,则没有消息传送
        if(comm_size==1)
        {
            printf("只有我这一个进程,没有进程向我发消息\n");
        }
        else
        {
            int i;
            // 用来存放消息来源进程号
            int other_rank;
            for(i=1;i<comm_size;i++)
            {
                // 0号进程接收消息,根据消息内容(其它进程号)判断是哪个进程发来的消息,打印信息
                MPI_Recv(&other_rank,1,MPI_INT,i,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
                printf("进程%d发来消息\n",other_rank);
             }
        }
    }

    MPI_Finalize();
    return 0;
}

3.MPI点对点标准非阻塞通信

/*
 * MPI点对点非阻塞通信
 *
 * 阻塞与非阻塞的区别(简单描述)
 * 举个例子,你要烧一壶水,在烧水的过程中你可以去做其它的事情,那么就算非阻塞的
 * 若你一直在水壶旁等水烧开,那就是阻塞的
 * 再比若MPI函数发送消息,消息量可能很大,可能会很耗时间,
 * 若进程一直等待,直到消息发送完才去做其它事情,那就是阻塞的
 * 若进程开始发送消息后,不等消息发送完,就可以去做其它事情,那就是非阻塞的
 *
 * MPI_Isend & MPI_Irecv & MPI_Wait & MPI_Test & MPI_Request & MPI_Status
 *
 * MPI_Isend() 与 MPI_Send(),MPI_Irecv() 与 MPI_Recv() 大致相同
 * 多了一个MPI_Request参数
 * MPI_Isend( , , , , , ,MPI_Request)
 * 少了一个MPI_Status参数,多了一个MPI_Request参数
 * MPI_Irecv( , , , , , ,MPI_Request)
 *
 * 阻塞式
 * 等待请求完成
 * MPI_Wait(MPI_Request*, MPI_Status*)
 * 非阻塞式
 * 测试请求是否完成
 * MPI_Test(MPI_Request*, int* flag, MPI_Status*)
 * if flag==1 则请求已完成
 *
 */

#include<stdio.h>
#include<mpi.h>

int main()
{
    int comm_size;
    int my_rank;
    MPI_Init(NULL,NULL);
    MPI_Comm_size(MPI_COMM_WORLD,&comm_size);
    MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);

    MPI_Request request;
    MPI_Status status;

    //0号进程向1号进程发送消息
    if(my_rank==0)
    {
        // MPI把一次非阻塞消息发送看作一次请求(可能是把这项任务交给操作系统去做,不太清楚),请求信息保存在request中
        MPI_Isend(&my_rank,1,MPI_INT,1,0,MPI_COMM_WORLD,&request);
    }
    // 1号进程接收0号进程发送来的消息,并打印
    else if(my_rank==1)
    {
        int tmp;
        // MPI把一次非阻塞消息接收也看作一次请求,请求信息保存在request中
        MPI_Irecv(&tmp,1,MPI_INT,0,0,MPI_COMM_WORLD,&request);
        // 阻塞式函数,等待消息发送请求完成
        // status是请求进度的状态信息
        MPI_Wait(&request,&status);
        // int flag=0;
        // MPI_Test(&request,&flag,&status);
        // if(flag){ printf("接收完成"); }
        printf("message:%d\n",tmp);
    }


    MPI_Finalize();
    return 0;
}

最后,欢迎大家加入MPI-OpenMP技术交流群,群号:288514428

点击链接加入群聊【MPI-OpenMP技术交流群】:https://jq.qq.com/?_wv=1027&k=5HpBfVg

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值