1.一个简单的hello world程序
mpi_hello.cpp
#include <iostream>
#include "mpi"
int main(int argv,char* argc[]){
MPI_Init(&argv,&argc);
cout<<"hello world"<<endl;
MPI_Finalize();
return0;
}
编译:mpicxx -o mpi_hello mpi_hello.cpp
运行:mpirun -np 3 ./mpi_hello
2.几个函数
(a)初始化MPI环境:int MPI_Init(int *argv,char **argc);
(b)结束MPI程序的运行:int MPI_Finalize(void);
这里只是告知该MPI的并行代码执行结束,而不是整个程序结束执行退出。在MPI_Finalize之后的代码还是会继续串行执行。例如:
#include "mpi.h"
#include <stdio.h>
#include <math.h>
#include <unistd.h>
#include <iostream>
using namespace std;
int main(int argc, char *argv[]){
int myid; // 当前进程的编号
int numprocs; // 当前进程的名称
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
MPI_Get_processor_name(processor_name,&namelen);
inti;
for(i=0; i<4; ++i){
cout<<"I'm"<<myid<<", sending "<<i<<endl;
sleep(1);
if(0 == myid && 0 == i){
MPI_Barrier(MPI_COMM_WORLD); //进程0将一直等待,直到其他并行进程执行结束
}
}
//MPI_Finalize(); //由于未执行MPI_Finalize,进程0无法感知到其他进程已退出
return0;
}
(c)获取进程个数:intMPI_Comm_size(MPI_Comm comm, int *size);
(d)获取当前进程编号rank,该值范围[0,p-1],p为并行进程个数:intMPI_Comm_rank(MPI_Comm comm, int *rank);
注:并不是编号为0的进程就是主进程用于接收其他进程发送的消息,而是调用Recv函数的进程接收消息,调用Send函数的进行发送消息。
(e)通信域(通信空间):MPI_COMM_WORLD。一个通信空间是一个进程组和一个上下文的组合。上下文可看作为组的超级标签,用于区分不同的通信域。在执行函数MPI_Init之后,一个MPI程序的所有进程形成一个缺省的组,这个组的通信域即被写作MPI_COMM_WORLD。该参数是MPI通信操作函数中必不可少的参数,用于限定参加通信的进程的范围。这类似于namespace,但是通信域不仅包括了组的标示符,还包括组里面的进程。
(f)发送消息:intMPI_Send(void* buf, int count, MPI_Datatype datatype, int dest,int tag, MPI_Comm comm);
IN buf 发送缓冲区的起始地址
IN count 要发送信息的元素个数(元素个数不一定等于字节个数,因为一个元素可能包含多个字节)
IN datatype 发送信息的数据类型
IN dest 接收消息进程的rank值
IN tag 消息标签(标识消息)
IN comm 通信域
(g)接收消息:intMPI_Recv(void* buf, int count, MPI_Datatype datatype, int source, inttag, MPI_Comm comm, MPI_Status *status);
OUT buf 接收缓冲区的起始地址,接收缓存应>=count*sizeof(datatype),否则将造成溢出
IN count 要接收信息的元素个数
IN datatype 接收信息的数据类型
IN source发送消息进程的rank值。使用MPI_ANY_SOURCE,可以接收来自任意进程的消息
IN tag 消息标签(只接收与发送消息中tag值相同的消息)。使用MPI_ANY_TAG,可以接收任意标签的消息
IN comm 通信域
OUTstatus status对象,包含实际接收到的消息的有关信息。可以通过status.MPI_SOURCE,status.MPI_TAG分别获取发送消息的进程和消息标签
(h)获取实际接收到消息的长度:intMPI_Get_count(MPI_Status status, MPI_Datatype datatype,int* count);
INstatus 接收操作的返回值.
INdatatype 接收缓冲区中元素的数据类型.
OUTcount 接收消息中的元素个数.
(i)获取指定通信域中的进程数:int MPI_Comm_size(MPI_Comm comm,int &size);
INcomm 通信域
OUTsize 通信域中的进程数
(j)MPI基本数据类型与C++类型的对应关系
MPI_BYTE |
| MPI_CHAR | signed char |
MPI_DOUBLE | double | MPI_FLOAT | float |
MPI_INT | int | MPI_LONG | long |
MPI_LONG_DOUBLE | long double | MPI_PACKED |
|
MPI_SHORT | short | MPI_UNSIGNED_CHAR | unsigned char |
MPI_UNSIGNED | unsigned int | MPI_UNSIGNED_LONG | unsigned long |
MPI_UNSIGNED_SHORT | unsigned short |
|
|
Reference
1.MPI官方文档