MPI基础函数
1.MPI_Init();
2.MPI_Comm_size();
3.MPI_Comm_rank();
4.MPI_Send();
5.MPI_Recv();
6.MPI_Finalize();
MPI各个函数介绍
1.初始化MPI_Init
int MPI_Init(int* argc,char** argc[])
1)对并行环境进行初始化
2)后面的MPI_Finalize()函数对应
3)每个进行执行一次
4)MPI系统通过argc和argv得到命令行参数(argc为命令行参数数量,argv为字符串数组记录着各个命令行参数)
2.结束MPI_Finalize
int MPI_Finalize(void)
1)退出MPI系统,所有进程正常退出必须调用,表示并行代码结束,结束除了主进程外其他进程
2)主进程(rank=0)仍然运行,但不能有MPI函数
3.获取进程个数
int MPI_Comm_size(MPI_Comm comm,int* size)
1)获取进程个数size
2)comm为通信子,代表一组进程。一个通信子定义了一些可以相互通信的进程集合。
3)MPI_Comm_World为MPI中默认通信子,包含了所有启动MPI程序时创建的进程
4)进程组为group,为进程的识别符rank所组成的几何
4.获取进程ID
int MPI_Comm_rank(MPI_Comm comm,int* rank)
1)获取进程的rank值
5.发送消息
int MPI_Send(void *buff,int count,MPI_Datatype datatype,int dest,int tag,MPI_Comm comm)
1)buff 要发送的变量
2)count 发送的消息个数(不是长度,如发送一个int整数,则为1;发送"hello"字符串,则为6;常用strlen(str)+1来对字符串的count进行计算
3)MPI_Datatype datatype 发送的数据类型,MPI定义的数据类型
4)dest 目的地进程号,要发给的进程号
5)tag 消息标签,接收方需要有相同的消息标签才能接受该消息
6)MPI_Comm comm 通讯域,比向哪个组发送消息
6.接收消息
int MPI_Recv(void *buff,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm comm,MPI_Status *status)
1)buff 接收到消息要保存到哪个变量里面
2)count 接收消息的个数,它是接收数据长度的上界,具体接收到的数据长度可通过调用MPI_Get_count函数得到
3)MPI_Datatype datatype 接收的数据类型,为MPI定义的数据类型
4)int dest 接收端进程号,需要哪个进程接收消息
5)int tag 消息标签,需要与发送方tag值相同的消息标签才能接收消息
6)MPI_Comm comm 通讯域
7)MPI_Status *status 消息状态 接收函数返回时,将参数指示的变量中存放实际接收消息的状态信息,包括消息的源进程标识,消息标签,包含的数据项个数等
示例
下图为非0号进程使用MPI_Send给0号进程发送消息,0号进程使用MPI_Recv来接收非0号进程的消息。
#include <stdio.h>
#include <string.h>
#include "mpi.h"
void main(int argc, char* argv[])
{
//numprocs存储进程总数 myid存储当前进程标识符 source从哪个进程接收消息
//status存储接收消息后的状态信息 message字符数据存储消息内容
int numprocs, myid, source;
MPI_Status status;
char message[100];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
if (myid != 0) { //非0号进程发送消息
strcpy(message, "Hello World!");
MPI_Send(message, strlen(message) + 1, MPI_CHAR, 0, 99,
MPI_COMM_WORLD);
}
else { // myid == 0,即0号进程接收消息
for (source = 1; source < numprocs; source++) {
MPI_Recv(message, 100, MPI_CHAR, source, 99,
MPI_COMM_WORLD, &status);
printf("接收到第%d号进程发送的消息:%s\n", source, message);
}
}
MPI_Finalize();
} /* end main */
运行结果如图所示
下图形象的标识了上述操作(使用的标准阻塞接收发送方式)
重要说明
1.MPI标识一条消息的信息包含四个域
1)源:rank值
2)目的地:Send函数确定的
3)Tag Send函数确定
4)通信子:默认为MPI_COMM_WORLD
5)Group:有限/N
6)Context:用于标识该通讯空间
2.buffer的使用
至少可以容纳count个由datatype指明类型的数据
3.消息匹配
Source ==MPI_ANY_SOURCE 接收任意处理器来的数据
Tag == MPI_ANY_TAG 匹配任意tag值的消息
4.阻塞式消息传送中不允许Source==dest,否则会导致死锁
可以使用MPI_iSend和MPI_iRecv来接收消息