MPI集群通信函数的学习
前言
集群函数相对于点对点函数来说效率更高,MPI提供了丰富的通信形式。而且3.0版本以后提供了非阻塞的集群通信方式。
介绍
1. 广播(Broadcast)
图片会更直观一些
2. Gather
3.Scatter
这个就比较优秀了,与广播分发给每一个进程的数据都不相同。
4. Gather与Allgather
Allgather是让每一个进程都获取所有进程的数据。
自定义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;
}
‘’’