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

阻塞式点对点通信

#include <stdio.h>
#include "mpi.h"
#define n 1024
int main(int argc,char *argv[]){
    int myrank,nprocs,i;
    double a[n],b[n];
    MPI_Status status;
    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
    MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
    for(i=0;i<n;i++){
        a[i] = myrank;
        b[i] = 0;
    }
//阻塞式消息发送
//int MPI_Send(void *buf, int count, MPI_Datatype datatype,  
//            int dest, int tag, MPI_Comm comm)
    MPI_Send(a,n,MPI_DOUBLE,(myrank+1)%nprocs,99,MPI_COMM_WORLD);
//  buf: 所要发送消息数据的首地址
//  count: 发送消息数组元素的个数。不是字节数,而是指定数据类型的个数
//  datatype: 发送消息的数据类型。可是原始数据类型,或为用户自定义类型
//  dest: 接收消息的进程编号。取值范围是 0~np-1,或MPI_PROC_NULL  (np是comm中的进程总数)
//  tag: 消息标签。取值范围是 0~MPI_TAG_UB,用来区分消息
//  comm: 通信器



//阻塞式消息接收
// int MPI_Recv(void *buf, int count, MPI_Datatype datatype, 
//                 int source, int tag, MPI_Comm  comm, 
//                 MPI_Status *status)
    MPI_Recv(b,n,MPI_DOUBLE,(myrank-1+nprocs)%nprocs,99,MPI_COMM_WORLD,&status);
// buf: 接收消息数据的首地址
// count: 接收消息数组元素的最大个数。是接受缓存区的大小,表示接受上界,具体接受长度可用MPI_Get_count 获得
// datatype: 接收消息的数据类型
// source: 发送消息的进程编号。取值范围是 0~np-1,或MPI_PROC_NULL和MPI_ANY_SOURCE
// tag: 消息标签。取值范围是 0~MPI_TAG_UB,或MPI_ANY_TAG
// comm: 通信器
// status: 接收消息时返回的状态

    printf("b[0]=%f in process %d\n",b[0],myrank);
    MPI_Finalize();
    return 0;
}


注意死锁的发生

  • MPI_Send 要 receive 完之后才 return,如果大家都 send 那就死锁了,
    教程里解决死锁的办法是奇偶 rank 的执行顺序不同,奇的话是先收后发,偶的话是先发后收

MPI_Send与MPI_Recv

捆绑发送和接收,收发使用同一缓存区

int MPI_Sendrecv_replace(void *buff,int count,MPI_Datatype datatype,
int dest, int sendtag,int source, int
recvtag,MPI_Comm comm, MPI_Status *status)

posted @ 2020-10-20 14:26  economies  阅读(213)  评论(0)    收藏  举报