全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 python论坛
3322 3
2015-10-13

二、MPI与mpi4py

MPI是Message Passing Interface的简称,也就是消息传递。消息传递指的是并行执行的各个进程具有自己独立的堆栈和代码段,作为互不相关的多个程序独立执行,进程之间的信息交互完全通过显示地调用通信函数来完成。

Mpi4py是构建在mpi之上的python库,使得python的数据结构可以在进程(或者多个cpu)之间进行传递。

2.1、MPI的工作方式

很简单,就是你启动了一组MPI进程,每个进程都是执行同样的代码!然后每个进程都有一个ID,也就是rank来标记我是谁。什么意思呢?假设一个CPU是你请的一个工人,共有10个工人。你有100块砖头要搬,然后很公平,让每个工人搬10块。这时候,你把任务写到一个任务卡里面,让10个工人都执行这个任务卡中的任务,也就是搬砖!这个任务卡中的“搬砖”就是你写的代码。然后10个CPU执行同一段代码。需要注意的是,代码里面的所有变量都是每个进程独有的,虽然名字相同。

例如,一个脚本test.py,里面包含以下代码:



1


2



[color=rgb(248, 248, 242) !important]from mpi4py import [color=rgb(249, 38, 80) !important]MPIprint([color=rgb(230, 219, 93) !important]"hello world'')
[color=rgb(230, 219, 93) !important]print("my rank [color=rgb(102, 217, 239) !important]is: %d" %MPI.rank)




然后我们在命令行通过以下方式运行:

#mpirun –np 5 python test.py

-np5 指定启动5个mpi进程来执行后面的程序。相当于对脚本拷贝了5份,每个进程运行一份,互不干扰。在运行的时候代码里面唯一的不同,就是各自的rank也就是ID不一样。所以这个代码就会打印5个hello world和5个不同的rank值,从0到4.

2.2、点对点通信

点对点通信(Point-to-PointCommunication)的能力是信息传递系统最基本的要求。意思就是让两个进程直接可以传输数据,也就是一个发送数据,另一个接收数据。接口就两个,send和recv,来个例子:



1


2


3


4


5


6


7



[color=rgb(248, 248, 242) !important]import mpi4py.MPI [color=rgb(102, 217, 239) !important]as MPI

comm = MPI.[color=rgb(249, 38, 80) !important]COMM_WORLD
comm_rank = comm.[color=rgb(249, 38, 80) !important]Get_rank()
comm_size = comm.[color=rgb(249, 38, 80) !important]Get_size()
[color=rgb(184, 92, 0) !important]# point to point communicationdata_send = [comm_rank]*5comm.send(data_send,dest=(comm_rank+1)%comm_size)
data_recv =comm.[color=rgb(249, 38, 80) !important]recv(source=(comm_rank-[color=rgb(174, 129, 255) !important]1)%comm_size)[color=rgb(249, 38, 80) !important]print([color=rgb(230, 219, 93) !important]"my rank is %d, and Ireceived:" % comm_rank)print data_recv




启动5个进程运行以上代码,结果如下:



1


2


3


4


5


6


7


8


9


10



[color=rgb(248, 248, 242) !important]my rank [color=rgb(102, 217, 239) !important]is [color=rgb(174, 129, 255) !important]0, [color=rgb(102, 217, 239) !important]and I received:
[[color=rgb(174, 129, 255) !important]4, [color=rgb(174, 129, 255) !important]4, [color=rgb(174, 129, 255) !important]4, [color=rgb(174, 129, 255) !important]4, [color=rgb(174, 129, 255) !important]4
my rank [color=rgb(102, 217, 239) !important]is [color=rgb(174, 129, 255) !important]1, [color=rgb(102, 217, 239) !important]and I received:
[[color=rgb(174, 129, 255) !important]0, [color=rgb(174, 129, 255) !important]0, [color=rgb(174, 129, 255) !important]0, [color=rgb(174, 129, 255) !important]0, [color=rgb(174, 129, 255) !important]0
my rank [color=rgb(102, 217, 239) !important]is [color=rgb(174, 129, 255) !important]2, [color=rgb(102, 217, 239) !important]and I received:
[[color=rgb(174, 129, 255) !important]1, [color=rgb(174, 129, 255) !important]1, [color=rgb(174, 129, 255) !important]1, [color=rgb(174, 129, 255) !important]1, [color=rgb(174, 129, 255) !important]1
my rank [color=rgb(102, 217, 239) !important]is [color=rgb(174, 129, 255) !important]3, [color=rgb(102, 217, 239) !important]and I received:
[[color=rgb(174, 129, 255) !important]2, [color=rgb(174, 129, 255) !important]2, [color=rgb(174, 129, 255) !important]2, [color=rgb(174, 129, 255) !important]2, [color=rgb(174, 129, 255) !important]2
my rank [color=rgb(102, 217, 239) !important]is [color=rgb(174, 129, 255) !important]4, [color=rgb(102, 217, 239) !important]and I received:
[[color=rgb(174, 129, 255) !important]3, [color=rgb(174, 129, 255) !important]3, [color=rgb(174, 129, 255) !important]3, [color=rgb(174, 129, 255) !important]3, [color=rgb(174, 129, 255) !important]3




可以看到,每个进程都创建了一个数组,然后把它传递给下一个进程,最后的那个进程传递给第一个进程。comm_size就是mpi的进程个数,也就是-np指定的那个数。MPI.COMM_WORLD 表示进程所在的通信组。

但这里面有个需要注意的问题,如果我们要发送的数据比较小的话,mpi会缓存我们的数据,也就是说执行到send这个代码的时候,会缓存被send的数据,然后继续执行后面的指令,而不会等待对方进程执行recv指令接收完这个数据。但是,如果要发送的数据很大,那么进程就是挂起等待,直到接收进程执行了recv指令接收了这个数据,进程才继续往下执行。所以上述的代码发送[rank]*5没啥问题,如果发送[rank]*500程序就会半死不活的样子了。因为所有的进程都会卡在发送这条指令,等待下一个进程发起接收的这个指令,但是进程是执行完发送的指令才能执行接收的指令,这就和死锁差不多了。所以一般,我们将其修改成以下的方式:



1


2


3


4


5



[color=rgb(248, 248, 242) !important]








原文  http://blog.csdn.net/zouxy09/article/details/49031845

转载请注明:绿安网 » Python多核编程mpi4py实践


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
2015-10-13 10:57:25
感谢分享
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2018-9-4 15:16:33
可以不在命令行运行,直接在脚本内给参数吗
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2018-9-16 21:09:24
看看!!
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群