这是关于MPI的一个问题。我需要两个不断修改一个变量的处理器,我希望两个处理器都能访问具有最新值的变量。
from mpi4py import MPI
from time import sleep
comm = MPI.COMM_WORLD
rank = comm.rank
assert comm.size == 2
msg = 0
sec = 10
if comm.rank == 0:
for i in range(sec):
print msg
sleep(1)
msg = comm.bcast(msg,root = 1)
else:
for i in range(sec*2):
msg += 1
sleep(0.5)
comm.bcast(msg,root = 1)
所以我期待程序打印出类似的东西:0 2 4 ...
但程序结果打印出来:0 1 2 3 4 5 6 7 8 9
我很好奇mpi4py中是否存在一个机制,使得两个处理器共享变量 msg ?也就是说,每当处理器1修改 msg 时,新值立即可供处理器0使用。换句话说,我希望处理器0访问 msg 而不是等待处理器1对 msg 所做的每一次更改。
答案 0 :(得分:3)
我认为你对分布式内存编程的工作方式感到困惑。在MPI中,每个进程(或级别)都有自己的内存,因此当它通过加载/存储操作更改值时(就像你用msg + = 1做的那样),它不会影响另一个进程的值。处理。更新远程值的唯一方法是发送消息,您正在使用comm.bcast()调用。这会将{1}的本地值从等级1发送到所有其他等级。在此之前,排名0无法知道排名1上发生了什么。
如果你想在进程之间拥有共享值,那么你可能需要看看其他东西,也许是线程。如果切换到OpenMP,你将失去MPI的分布式能力,但这可能不是你首先需要的MPI。有很多方法可以通过分布式内存模型(例如统一并行C,全局数组等PGAS语言)来实现这一点,但是你总会遇到延迟问题,这意味着有一些时间可以排在队列上0和1不同步,除非你有某种保护来强制执行它。
答案 1 :(得分:2)
正如Wesley Bland所提到的,在纯粹的分布式内存环境中,这是不可能的,因为内存不是共享的。
然而,MPI已经在一段时间内(自1997年以来)在MPI-2中允许这样的事情,作为单边沟通;这些已在MPI-3(2012)中得到了显着更新。这种方法可以有真正的优势,但必须要小心一点;由于内存并未真正共享,因此每次更新都需要昂贵的通信,而且过度依赖共享状态很容易在代码中意外地造成严重的可伸缩性/性能瓶颈。
Using MPI-2书中有一个使用MPI-2单边通信实现计数器的例子; C中描述并实现了该计数器的简单版本in this answer。在mpi4py发行版中,在'demos'下,'nxtval'演示中有这些相同计数器的实现;与nxtval-onesided.py相同的简单计数器和更复杂但更具伸缩性的实现,也如使用MPI-2一书中描述的nxtval-scalable.py。您应该能够在上面的代码中或多或少地使用这些实现中的任何一个。