MPI 就是个并行计算框架,模型也很直接——就是多进程。而openmp是多核計算。和hadoop不同,它不提供计算任务的map和reduce,只提供了一套通信接口,需要程序员来完成这些任务;它也不提供冗余容错等机制,完全依赖于其下层的可靠性。但是因为把控制权几乎完全交给了程序员,所以有很大的灵活性,可以最大限度地榨取硬件性能。超级计算机上的运算任务,基本上都是使用MPI来开发的。
1. 最简单的:Hello world
代码如下:
hello.c
#include <stdio.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
MPI_Init(&argc, &argv); //初始化MPI环境
printf("Hello world!\n");
MPI_Finalize(); //结束MPI环境
return 0;
#include <mpi.h>
int main(int argc, char *argv[])
{
MPI_Init(&argc, &argv); //初始化MPI环境
printf("Hello world!\n");
MPI_Finalize(); //结束MPI环境
return 0;
}
编译:mpicc -o hello hello.c
运行:
mpirun -np 4 ./hello mpiexec -n 4 ./hello这之后会输出4个
Hello
World
, 当然mpirun
和mpiexec
你只要运行一个就OK了,这两句是等价的,你也可以修改开启的进程数目,即-n后的参数。mpirun是MPI各个实现的启动MPI的方式,而mpiexec是MPI标准启动方式,使用mpiexec
要更好一些。
基本的API:
初始化:
int MPI_INit(int *argc, char *argv[]);//这句应该放在所有并行操作的最前面。
int MPI_Initialized(int *flag);//是否初始化, 结果保存在flag中
并行结束:
int MPI_Finalize();
int MPI_Comm_size(MPI_Comm comm, int *size); //把comm通信下的processor的个数存入size中 int MPI_Comm_rank(MPI_Comm comm, int *rank); //当前进程的的标识存入rank中(0 ~ size-1)comm为
_WORLD
时,表示当前程序所有能用的进程。一般,上面这两句在大部分MPI程序中都是紧挨着
MPI_Init()
的。使用这两个函数,可以方便的实现master-slave的并行模式。
例如:
if ( rank == 0 ) DoMaster();//执行进程1
else if ( rank == 1 ) DoSlave1();//执行进程2
else if ( rank == 2 ) DoSlave2();//执行进程3
进行时间测定:
int MPI_Wtime(void); //程序此刻的时间戳
int MPI_Wtick(void); //两个时钟脉冲间隔
进程之间通信规范:
进程之间传输,也就是send
和recv