mpi学习日志(3):mpi4py与广播

来源:互联网 发布:芜湖java培训 编辑:程序博客网 时间:2024/05/21 08:59

前面我们学习了点对点通信,那是关于两个点的通信.今天,我们学习多个点之间的通信.首先,我们学习广播.

所谓广播,就是说某个进程要向其他所有进程发送数据,而不是单独某个进程.


显然,一次的广播可以等价为许多次的点对点通信,我们可以用学过的send和recv去实现广播.


代码:



运行结果:



我们看见,5个进程中,除了要广播的进程0,后面4个进程都收到了进程0发送的一个列表.


效率?

但这样就完了吗?这样实现有什么问题?答案是效率.

用时间复杂度去说话,假设拷贝一份数据是O(1)复杂度,有n个进程.那么后面4个进程的时间复杂度是O(1),而进程0的时间复杂度是O(n).

在单机上跑这n个进程好像这没什么所谓,CPU始终在工作,时间复杂度也是O(n)级别.但假如是n台机器分别跑这n个进程,那么问题就大了.

第0台机器始终在发送数据,而其他机器的大部分时间都在排队,等第0台机器往自己发送数据.这样的话,这堆机器要运行完这堆进程,需要O(n)时间.这居然和一台机器所需时间一样!


bcast:

为了解决这个问题,我们可以像p2p那样做,有数据的机器都帮忙向没有数据的机器发送数据,这样的话时间复杂度是可以降低到O(logn)的!

要实现这样的算法,是很困难的,尤其是mpi下这些进程都不共享数据,难上加难.

幸好,mpi帮我们实现了这个功能,我们只要使用一个统一的函数就行了,那就是bcast


代码:



运行结果:



可以看到,运行结果和前面的完全一样.


代码解释:

在代码里,新出现的函数就只有bcast.

我们注意到,无论是广播者,还是被广播者,都是调用bcast函数,而不像点对点那样一个send另一个recv.

在以后更多的通信方式里,都会像这样发送方和接收方使用同一个函数,只是参数可能不一样.

说到参数,发送方的第一个参数和send一样,也是要发送的数据.

后面还有一个root参数,这个参数接收方也有,也是实参一样.这个root是表示要广播的人是谁.这里就是我们的进程0.

不同的是,接收方的第一个参数是none.这个照写就是了,后面许多函数也是这样的.

返回值方面,我这里发送方没有接收返回值.事实上,发送方和接收方的返回值都是一样的,都是发送方要发送的数据.也就是说,广播者也会广播到自己.


0 0
原创粉丝点击