https://wenku.baidu.com/view/3318805b69eae009581bec35.html
4.2 6个基本函数组成的mpi子集
#include "mpi.h" /* 提供mpi函数和数据类型定义 */
int main(int argc, char** argv) {
int rank,size,tag =1;
//senddata, recvdata 是int型
int senddata, recvdata;
//消息状态
MPI_Status status;
//初始化
MPI_Init(&argc, &argv);
//MPI_COMM_WORLD 全局——所有进程集合
// MPI_Comm comm 当前
//获取当前进程在指定通信域(MPI_COMM_WORLD)中的编号 -> 区分自身和其他程序
int MPI_Comm_rank(MPI_Comm comm,int *rank);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
//获取指定通信域的进程数 -> 确定完成比例
int MPI_Comm_size(MPI_Comm comm,int *size);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if(rank==0){
senddata=9999;
/* 消息缓冲 即信内容
* *buf 起始地址
* count 数据个数
* datatype 数据类型
消息封装 即信封
* dest/source 目标/源进程编号
* tag 消息标签
* comm 通信域
*/
int MPI_send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm);
//发送数据到进程1
//第四个参数即目的地进程编号
MPI_send(&senddata, 1, MPI_INT, 1, tag, MPI_COMM_WORLD);
}
if(rank==1){
int MPI_Recv(void*buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status);
//从进程0接收数据
MPI_Recv(&recvdata, 1, MPI_INT, 0 , tag, MPI_COMM_WORLD);
}
int MPI_Finalize(void);
MPI_Finalize();
return 0;
}
4.3 MPI消息
4.3.1数据类型(略)
Load elements -> load datatype2MPI_Datatype
4.3.2 消息标签
为什么需要消息标签?
区分相同类型的消息传输
//假设没有tag
//Process P
MPI_send(A,32,std::string,Q);
MPI_send(B,16,std::string,Q);
//Process Q
MPI_Recv(X,32,std::string,P);
MPI_Recv(Y,16,std::string,P);
/*
传送A的前32个字节给X;
传送B的前16个字节给Y;
尽管消息B后发送 但可能更快地到达进程Q 就被第一个recv接收到了x里,所以我们得加上标签
*/
//有tag
int tag1 = 1;
int tag2 = 2;
//Process P
MPI_send(A,32,std::string,Q,tag1);
MPI_send(B,16,std::string,Q,tag2);
//Process Q
MPI_Recv(X,32,std::string,P,tag1);
MPI_Recv(Y,16,std::string,P,tag2);
4.3.3 通信域
1.进程组:进程的有限有序集
一个进程用它在通信域里的编号来标识
//获取组大小
MPI_Comm_size(communicator, &group_size);
//获取进程编号
MPI_Comm_rank(communicator, &my_rank);
2.通信上下文:非显式
两部分来描述进程间的通信关系
// 一般size = rank + 1
int my_rank = 9;
int group_size = 10;
int color = my_rank %3;
int key = my_rank/3;
MPI_Comm MyWorld,SplitWorld;
int MPI_Comm_split(MyWorld,color,key,&SplitWorld);
// my_rank = global_shard_id
// color = mpi_rank();
// 3 = mpi_size()
// key = local_shard_id
//color = my_rank %3 = global_shard_id%mpi_size() = mpi_rank()
//key = my_rank/3 = global_shard_id/mpi_size() = local_shard_id