1. 程式人生 > 實用技巧 >高效能平行計算-點對點通訊

高效能平行計算-點對點通訊

阻塞式點對點通訊

#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 的執行順序不同,奇的話是先收後發,偶的話是先發後收