一、环境搭建
在Ubuntu运行
1.gcc/g++环境配置
Ubuntu默认没有安装gcc/g++等编译环境。
为简化环境配置,可以使用build-essential软件包。该软件包内包含了gcc/g++/gfortran等编译器.
sudo apt install build-essential
2.mpich环境配置
使用如下命令安装mpich:
sudo apt install mpich
3.安装完成后,各个版本信息查看:
(1)gcc版本查看(C语言编译器):
gcc -v
(2)g++版本查看(C++编译器)
g++ -v
(3)mpicc版本查看(使用C语言编写的MPI程序,需要使用mpicc进行编译)
mpicc -v
(4)mpic++版本查看(使用C++编写的MPI程序,需要使用mpic++进行编译)
mpic++ -v
二、基本程序编译运行
1.mpi程序编译
mpicc -o XXX XXX.cpp // 使用C语言编写的MPI程序
mpic++ -o XXX XXX.cpp // 使用C语言编写的MPI程序
2.mpi程序运行
mpirun -np Y ./XXX
// Y表示的是一个数字,代表并行运行的进程数目。
// XXX表示源程序文件
3.实例
每个程序猿的开始:hello world
// hello.cpp
#include <iostream>
#include "mpi.h"
//使用了MPI程序需要包含mpi.h头文件
using namespace std;
int main(int argc, char** argv)
{
MPI_Init( &argc , &argv);
cout<<"Hello world!"<<endl;
MPI_Finalize();
return 0;
}
编译:
mpic++ -o hello.o hello.cpp
运行:
mpirun -np 3 ./hello.o
// 3:3个进程 运行hello.o
三、MPI基本数据类型
MPI 数据类型 | C语言数据类型 |
---|---|
MPI_CHAR | char |
MPI_SHORT | short int |
MPI_INT | int |
MPI_LONG | long / long int |
MPI_FLOAT | float |
MPI_DOUBLE | double |
MPI_LONG_DOUBLE | long double |
MPI_UNSIGNED_CHAR | unsigned char |
MPI_UNSIGNED_SHORT | unsigned short |
MPI_UNSIGNED_INT | unsigned int |
MPI_UNSIGNED_LONG | unsigned long |
MPI_BYTE | |
MPI_PACKED |
四、MPI基本函数
//初始化函数。MPI_INIT是MPI程序的第一个调用,完成MPI程序的所有初始化工作,启动MPI环境,标志并行代码的开始,因此要求main函数必须带参数运行
int MPI_Init(int *argc, char **argv)
//退出/结束函数。它是MPI程序的最后一个调用,结束MPI程序的运行,是MPI程序的最后一条可执行语句。它标志并行代码的结束,结束除主进程外其它进程
int MPI_Finalize(void)
//允许在MPI_Init前使用的函数,检测MPI系统是否已经初始化
int MPI_Initialized(int* flag)
//获取处理器的名称,在返回的name中存储所在处理器的名称,resultlen存放返回名字所占字节,应提供参数name不少于MPI_MAX_PRCESSOR_NAME个字节的存储空间
int MPI_Get_processor_name(char* name, int* resultlen)
//返回调用时刻的墙上时间,用浮点数表示秒数,墙上时钟时间wall clock time,也叫时钟时间,是指从进程从开始运行到结束,时钟走过的时间,这其中包含了进程在阻塞和等待状态的时间。用来计算程序运行时间。
double MPI_Wtime(void)
五、几个程序案例
1.Print:输出每个进程的信息和运行时间
// print.cpp
#include <iostream>
#include "mpi.h"
using namespace std;
int main(int argc, char** argv)
{
int pid, pnum,namelen;
double starttime;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init( &argc , &argv);
//初始化
starttime=MPI_Wtime();
//开始时间
MPI_Comm_size( MPI_COMM_WORLD , &pnum);
//获取通信域内进程个数
MPI_Comm_rank( MPI_COMM_WORLD , &pid);
//获取本进程的rank
MPI_Get_processor_name( processor_name , &namelen);
//获取processor_name
cout<<"this is "<<pid<<" of "<<pnum<<" and my name is "<< processor_name <<endl;
cout<<"this is "<<pid<<" and spend ";
printf("%.6lf s\n",MPI_Wtime()-starttime);
//输出信息
MPI_Finalize();
//结束并退出
return 0;
}
mpic++ -o print.o print.cpp
mpirun -np 3 ./print.o
2.π的计算
莱布尼兹公式:
π = 4 ( 1 − 1 3 + 1 5 − 1 7 + . . . + ( − 1 ) n 1 2 n + 1 + . . . ) \pi = 4(1 - \frac1 3 + \frac1 5 - \frac1 7 + ... +(-1)^n\frac1 {2n+1} + ...) π=4(1−31+