tar xzvf mpich-x.x.x.tgz
。cd mpich-x.x.x
./configure --prefix=/usr/local/mpich-x.x.x
这里可能会有一些出错提示,缺少编辑器啥的,按需求确认安装C、C++、F77和F90编译器即可。
sudo apt-get install fort77
,sudo apt-get install gfortran
sudo make
sudo make install
/usr/local/mpi/bin
这个文件夹等等。1、创建文件/etc/profile.d/user.sh,包含以下内容:
export PATH=$PATH:/usr/local/mpi/bin
export MANPATH=$MANPATH:/usr/local/mpi/man
2、创建文件/etc/ld.so.conf.d/mpi.conf,包含以下内容:
/usr/local/mpi/lib
/usr/local/mpi/lib/shared
3、执行以下命令,使两个文件生效:
source /etc/profile.d/user.sh
source /sbin/ldconfig
4、在/etc/profile文件中添加库共享路径
执行sudo gedit /etc/profile
,然后在其中加入一行
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
5.使该配置文件生效
source /etc/profile
在解压出来的MPI安装目录下有个examples文件夹,里面有若干示例程序可供测试。
mpicc hellow.c -o hellow
进行编译。mpirun -np N hellow
这里的N改成一个常数,表示你要用来运行这个并行程序的节点。当然,如果不是在集群环境上,你一个CPU就一个节点,进程数也就是一个最多,本地机子默认的编号就是0。你N的不同无异于就是把程序跑N遍而已。
MPI:英文全称是Message Passing
Interface,这个就很明了了,信息传递接口,是独立于语言的通信协议(标准),是一个库。不是一个编程语言,它有自己的实现。
在MPICH中,mpirun是MPI程序的启动脚本,它简化了并行进程的启动过程,尽可能屏蔽了底层的实现细节,从而为用户提供了一个通用的MPI并行机。在用mpirun命令执行并行程序时,参数-np指明了需要并行运行的进程个数。mpirun首先在本地结点上启动一个进程,然后根据/usr/local/share/machines.LINUX文件中所列出的主机,为每个主机启动一个进程。若进程数比可用的并行节点数多,则多余的进程将重新按照上述规则进行。按这个机制分配好进程后,一般会给每个节点分一个固定的标号,类似于身份证了,到时再消息传递中会用到。
节点之间传递消息,一般要先认证身份,每次传递都要认证身份比较麻烦。所以,可以搞一个“通行证”一样的东西,使得传递消息变得更加便捷。示例命令行代码如下:
ssh-keygen -t dsa
cp id˙dsa.pub authorized˙keys
chmod go-rwx authorized˙keys
ssh-agent $SHELL
ssh-add
#include
#include
int main(int argc, char * argv[])
{int myrank, nprocs;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
printf("rank%dof%d:Hello,world!\n",myrank, nprocs);
MPI_Finalize();
return 0;
}
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
printf(”rank %d of %d: Hello, world!\n”, myrank, nprocs);
MPI_Finalize();
#include
int main (int argc, char *argv[])
{
int myrank, a;
MPI_Status stat;
MPI_Init (&argc, &argv);
MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
a = myrank + 10;
if (myrank == 0)
MPI_Send (&a, 1, MPI_INT, 1, 9, MPI_COMM_WORLD);
else (myrank == 1)
MPI_Recv (&a, 1, MPI_INT, 0, 9, MPI_COMM_WORLD, &stat);
MPI_Finalize ();
return 0;
}
通俗地说,MPI_Send的六个元素的大概意思就是,我要从内存的那个位置开始,连续取多少个某种类型的数据,这就是消息数据。信封上写上这是要送给序号为多少的节点的第几封信,指明这是申通快递寄过去,这就是消息信封的三个元素。反之亦然,MPI_Recv就要开辟从某个位置开始的多少个这种类型的数据内存,然后去找对方寄送给自己的第N封消息,要是申通的,如果收到了,反馈一个状态。
如何理解并行计算的计算流程呢?我是这样想的。按并行的方式写一段并行的程序,然后在集群环境里主机上运行apirun
的时候指定需要的进程数。接着,计算机在集群环境下尽可能找到对应 的节点,分配进程任务并给他们编号。此后,将程序拷贝一份给每一个节点,每个节点在这个共同的工作中都担任着一份角色。接着,他们就按程序中设计的方式,各自运行着由自己编号决定的自己的那一段代码,相互之间进行通讯,最后共同完成这项任务。那么,不同节点程序进行有早晚,如何保证协调一致有序进行呢?比如说,你可以等呀,可以找个地方先寄存一下你给别人的消息之类的。这就涉及到了MPI通讯的阻塞型和非阻塞型通讯模式。
注意权限不足的引起的错误,有时候并不会明显地报给你,多加
sudo
跑命令总是没错。