4

这是关于 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上生成。

4

2 回答 2

5

我认为您对分布式内存编程的工作方式感到困惑。在 MPI 中,每个进程(或等级)都有自己的内存,因此当它通过加载/存储操作更改值时(就像您使用 msg += 1 所做的那样),它不会影响另一个变量的值过程。更新远程值的唯一方法是发送消息,您正在使用 comm.bcast() 调用。这会将排名 1 的本地值发送msg到所有其他排名。在此之前,等级 0 无法知道等级 1 上发生了什么。

如果你想在进程之间共享值,那么你可能需要看看别的东西,也许是线程。如果您切换到 OpenMP,您将失去 MPI 的分布式功能,但这可能不是您首先需要 MPI 的。有一些方法可以使用分布式内存模型(例如统一并行 C、全局数组等 PGAS 语言),但您总是会遇到延迟问题,这意味着会有一段时间排名上的值0 和 1 不会同步,除非您有某种保护措施来强制执行它。

于 2013-07-09T13:36:53.883 回答
2

正如 Wesley Bland 所提到的,这在纯分布式内存环境中是不可能的,因为内存不是共享的。

然而,MPI 已经有一段时间(自 1997 年以来)允许在MPI-2中使用类似的东西,作为单方面的通信;这些已在MPI-3 (2012) 中进行了重大更新。这种方法可以有真正的优势,但必须要小心一点;由于内存不是真正共享的,因此每次更新都需要昂贵的通信,并且由于过度依赖共享状态,很容易在代码中意外地造成重大的可扩展性/性能瓶颈。

使用MPI-2书有一个使用 MPI-2 单向通信实现计数器的示例;该计数器的一个简单版本在 C中的这个答案中进行了描述和实现。在 mpi4py 发行版中,在“演示”下,在“nxtval”演示中有这些相同计数器的实现;与nxtval-oneside.py相同的简单计数器和更复杂但更可扩展的实现,也如使用 MPI-2 书中所述,作为nxtval-scalable.py。您应该能够在上述代码中或多或少地使用这些实现中的任何一个。

于 2013-07-09T14:51:49.080 回答