MPI集群通信函数的学习

前言

集群函数相对于点对点函数来说效率更高,MPI提供了丰富的通信形式。而且3.0版本以后提供了非阻塞的集群通信方式。

介绍

1. 广播(Broadcast)

图片会更直观一些
MPI集群通信函数的学习

2. Gather

MPI集群通信函数的学习

3.Scatter

这个就比较优秀了,与广播分发给每一个进程的数据都不相同。
MPI集群通信函数的学习

4. Gather与Allgather

Allgather是让每一个进程都获取所有进程的数据。
MPI集群通信函数的学习

自定义MPI数据类型并传送

重点理解一下函数各个参数就明白了,且来看函数原型

MPI_Type_struct(			oldtype_nums 结构体类型个数,相同类型一块空间
							,blocklens_array 每个类型所对应的那块空间的长度
							,displs_array	每块的起始地址
							,old_type_array 指定每个块的起始地址与头的偏移量
							,&new_mpi_type 新类型
							);

这里假设有一个集群,需要对每一个电脑的运算速度进行排序,如果使用了结构体会更方便。
就下面这段代码来说,用Allgather让每个电脑获得所有电脑的速度,然后每个电脑遍历一遍这个数据,记录下比自己运算速度大的个数,最后就可以知道自己在急群众运算速度的排名了。

#include <stdio.h>
#include "mpi.h"
#include<time.h>
#include<malloc.h>

#define oldtype_nums 2
#define INT_NUMS 1
#define LONG_NUMS 1

int main (int argc,char **argv){

typedef struct{
    long speed;
    int index;
}Computer;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Status status;
int size,rank,speed,i,index;
MPI_Init(&argc,&argv);
MPI_Comm_size(comm,&size);
MPI_Comm_rank(comm,&rank);


int blocklens_array[oldtype_nums]; //用于存放每个块的长度
MPI_Aint displs_array[oldtype_nums];//使用MPI_Aint,单个元素的存放空间可以放得下地址。
MPI_Datatype old_type_array[oldtype_nums];//用于存放每个块的类型


MPI_Datatype MPI_Computer;



Computer mycomputer;

old_type_array[0]=MPI_LONG;
old_type_array[1]=MPI_INT;
blocklens_array[0]=1;
blocklens_array[1]=1;

MPI_Address(&mycomputer.index,&displs_array[1]);
MPI_Address(&mycomputer.speed,&displs_array[0]);
displs_array[1]=displs_array[1]-displs_array[0];
displs_array[0]=0;

MPI_Type_struct(oldtype_nums,blocklens_array,displs_array,old_type_array,&MPI_Computer);
MPI_Type_commit(&MPI_Computer);


Computer *computer=NULL;
computer = (Computer*)malloc(sizeof(Computer));

Computer *computers=NULL;
computers = (Computer*)malloc(sizeof(Computer)*size);

computer->speed=rank;
computer->index=0;



MPI_Allgather(&computer->speed,1,MPI_Computer,&computers->speed,1,MPI_Computer,comm);
for(i=0;i<size;i++)
{
    if(computers[i].speed > computers[rank].speed)
       (computers[rank].index)++;
}

printf("The index of process %d is %d ,speed is %ld\n",rank,computers[rank].index,computers[rank].speed);

MPI_Finalize();

return 0;

}
‘’’