MPI是一种可以用于并行计算的工具,借助它你可以实现比较基础的并行计算。现在就让我们快速地上手这一工具。

这篇文章会告诉你什么

  • 安装MPI
  • 编写并编译含MPI功能的C代码
  • vmware虚拟机之间的免密通信
  • 多机的MPI并行计算

这篇文章不会告诉你什么

  • 安装Ubuntu
  • 命令行的使用
  • NFS挂载(文件将通过scp传输)
  • MPI的详尽语法和接口

使用MPI

首先,用以下命令在你的电脑上安装MPI:

sudo apt install libopenmpi-dev

这里准备了一份使用了MPI的C代码。请随意使用。

#include 

我把这个文件保存为mpi3.c(请原谅我随意的起名),你可以起任何名字。然后,我们用MPI专有编译工具mpicc编译我们的程序:

mpicc mpi3.c -o mpi3

如果你在虚拟机直接跑这个程序,也就是./mpi3,那么很大可能你会发现并没有多个处理器在帮你跑——因为你的虚拟机只有一个核。想要强行地达到并行的效果,可以使用mpirun的-np参数,它会自动帮你把一个核心切成多份处理器。

mpirun -np 5 mpi3

Voila!

e0986ad9e893cd4c8a07fc0029b2dc80.png

虚拟机之间的免密通信

基本思路:生成各自的ssh key -> 把自己的公钥加入authorized_keys -> 用scp把公钥传给另一方 -> 对方也把公钥加入authorized_keys并传输回来 -> 完成免密

默认情况下,vmware虚拟机使用的是NAT网卡。如果你使用VMnet的话,也许要自己设置ip,这样挺麻烦的,还可能因为没有网络而在开机时卡在加载界面。

使用命令ifconfig,找到那个192.168开头的ip地址,这就是虚拟机之间互相通信时要用到的地址。

7a66886b04842bfc95f67bed7f0587c2.png

在我的实验过程用到了GUI界面的ubuntu desktop,以及只有命令行界面的ubuntu server。它们的ip地址分别是192.168.22.150,192.168.22.151。讲道理,要是每次都要输入这么一长串数字,还是比较繁琐的,所以我们到hosts里去给这两个ip起个名字。

sudo vim /etc/hosts

c989a24ef5548c5c0519ef67d1eee996.png
前面两行是自带的,在后面加上自己写的即可。

记得在gui的虚拟机也这么加上这两句。从此你就只需要用hostgui, hostser这两个名字来指代对方。测试一下吧!在命令行这里,我们用ssh访问自己。如果你没有ssh这个东西,那请自行安装一个。

ssh hostser

a601baf7f11b7ee137915949045d00e0.png

为什么我自己连接我自己还要输入密码呢?当然了,因为你的机器其实并不知道是谁要来连接,不然的话不如就直接告诉你“禁止套娃”。

那么问题来了,如何让机器知道你的身份,然后直接给你放心呢?这里就要用到ssh key。如果你之前用过github这类东西,你应该会知道大概怎么回事。我们这里要用到的ssh key存放在~/.ssh目录下,有两个文件,分别是id_rsa和id_rsa.pub。

带.pub的公钥文件就是交给对方的文件。当你要免密连接对方,他就会用你的公钥加密一串信息,让你用你的私钥解密。要是解密成功了的话,就可以直接放行,不必再输入密码。

如果你之前没用过github,或者本机上没用过github也没关系,我们马上生成一个。

ssh-keygen -t rsa

请一直按回车即可。生成完毕之后,你就可以在~/.ssh里面发现那两个id_rsa文件。现在要做的就是,把.pub里面的内容复制到文件authorized_keys里面。凡是能和这个文件里的公钥匹配的来访者,就可以免密登录。图个方便,我们直接把id_rsa.pub复制成authorized_keys:

cp id_rsa.pub authorized_keys

现在再尝试ssh连接自己,应该就可以不用输入密码了。

但是免密连接自己并不是我们的目的。我们的目的是让两个并行计算的计算机之间可以免密访问。现在,确保你的另一台虚拟机在线(比如我的就是“hostgui”,当前用户为“ricolove”),然后用scp命令将authroized_keys传输过去:

scp authorized_keys ricolove@hostgui:~/.ssh/

然后你会需要输入对方用户的密码。输入一次并完成传输,再尝试用ssh连接过去,你就会发现,不需要密码了!

ssh hostgui

先别急着退出ssh连接,因为现在我们只能做到hostser -> hostgui的单向免密连接,所以还需要把hostgui的公钥加入authorzied_keys里,再传输回hostser。

cat id_rsa.pub >> authorized_keys
scp authorized_keys ricolove@hostser:~/.ssh
ssh hostser

如果你成功地免密连接回来,那么恭喜你,免密传输完成了!

最后一步

现在,要让程序并行计算而不经过网络文件系统挂载,就需要*相同的可执行文件放在双方的*同一目录下。使用scp,我们把mpi3从hostgui传输过去:

$ pwd
/home/ricolove/code
$ ls
mpi3.c mpi3
$ scp mpi3 ricolove@hostser:~/code/

这时候,你可以试试为mpirun加入host参数,执行以下命令:

mpirun -host hostgui,hostser mpi3

你会发现,虽然能执行,但是并没出现多核的情况。那么,如果我们像上面说的那样,加入-np参数,会发生什么呢?

$ mpirun -host hostgui,hostser -np 10 mpi3
--------------------------------------------------------------------------
There are not enough slots available in the system to satisfy the 10 slots
that were requested by the application:
  mpi3

Either request fewer slots for your application, or make more slots available
for use.
--------------------------------------------------------------------------

它会告诉你,并没有那么多的slot给你用,也就是说不能像本地运行那样直接切分核心。这时候,我们就需要用一个hostfile文件来为两节点指定slot数量。

vim hostfile

在打开的新文件里输入:

hostgui slots=5
hostser slots=5

保存并退出,执行指定了hostfile的mpirun:

mpirun -host hostgui,hostser --hostfile hostfile -np 10 mpi3

b214b24de6a5dc2eee3f5b3c11116b15.png

大功告成!

现在,请你忘掉刚才所看到的内容,学习MapReduce或者Hadoop。大人,时代变了,MPI应该被扔进历史的地下储藏室。

祝你生活愉快,再见。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐