gpt4 book ai didi

mpi 中的 Python 多处理

转载 作者:太空狗 更新时间:2023-10-29 17:48:07 44 4
gpt4 key购买 nike

我有一个使用多处理模块编写的 python 脚本,用于更快地执行。计算是令人尴尬的并行,因此效率与处理器数量成比例。现在,我想在 MPI 程序中使用它,该程序管理跨多台计算机的 MCMC 计算。此代码调用了调用 python 脚本的 system()。但是,我发现当以这种方式调用它时,使用 python 多处理的效率增益消失了。

如何让我的 python 脚本在从 MPI 调用时保持多处理的速度增益?

这是一个简单的例子,它类似于我想使用的更复杂的代码,但显示相同的一般行为。我编写了一个名为 junk.py 的可执行 python 脚本。

#!/usr/bin/python
import multiprocessing
import numpy as np

nproc = 3
nlen = 100000


def f(x):
print x
v = np.arange(nlen)
result = 0.
for i, y in enumerate(v):
result += (x+v[i:]).sum()
return result


def foo():
pool = multiprocessing.Pool(processes=nproc)
xlist = range(2,2+nproc)
print xlist
result = pool.map(f, xlist)
print result

if __name__ == '__main__':
foo()

当我从 shell 本身运行它时,使用“top”我可以看到三个 python 进程,每个进程在我的 16 核机器上占用 100% 的 cpu。

node094:mpi[ 206 ] /usr/bin/time junk.py
[2, 3, 4]
2
3
4
[333343333400000.0, 333348333450000.0, 333353333500000.0]
62.68user 0.04system 0:21.11elapsed 297%CPU (0avgtext+0avgdata 16516maxresident)k
0inputs+0outputs (0major+11092minor)pagefaults 0swaps

但是,如果我用 mpirun 调用它,每个 python 进程占用 33% 的 cpu,总体而言,运行时间大约是原来的三倍。使用 -np 2 或更多调用会导致更多进程,但不会加快计算速度。

node094:mpi[ 208 ] /usr/bin/time mpirun -np 1 junk.py
[2, 3, 4]
2
3
4
[333343333400000.0, 333348333450000.0, 333353333500000.0]
61.63user 0.07system 1:01.91elapsed 99%CPU (0avgtext+0avgdata 16520maxresident)k
0inputs+8outputs (0major+13715minor)pagefaults 0swaps

(附加说明:这是 Linux Debian 版本上的 mpirun 1.8.1,python 2.7.3 喘不过气来。我听说 system() 在 MPI 程序中并不总是被允许,但它在过去五年中一直为我工作这台计算机。例如,我在 MPI 程序中从 system() 调用了一个基于 pthread 的并行代码,并且它根据需要为每个线程使用了 100% 的 cpu。此外,如果您要建议运行 python 脚本串行并在更多节点上调用它...MCMC 计算涉及固定数量的链,这些链需要以同步方式移动,因此不幸的是无法以这种方式重新组织计算。)

最佳答案

OpenMPI's mpirun, v1.7 and later ,默认将进程绑定(bind)到核心——也就是说,当它启动 python junk.py 进程时,它将它绑定(bind)到它将运行的核心。这很好,并且是大多数 MPI 用例的正确默认行为。但是在这里,每个 MPI 任务都会 fork 更多的进程(通过 multiprocessing 包),而那些 fork 的进程继承了它们父进程的绑定(bind)状态——所以它们都绑定(bind)到同一个核心,相互争斗。 (顶部的“P”列将向您显示它们都在同一处理器上)

如果你 mpirun -np 2,你会发现两组三个进程,每个进程在不同的核心上,每个进程相互竞争。

使用 OpenMPI,您可以通过关闭绑定(bind)来避免这种情况,

mpirun -np 1 --bind-to none junk.py

或者选择一些其他的绑定(bind),这对于你运行的最终几何形状来说是有意义的。 MPICH 有 similar options with hydra .

请注意,子进程的 fork()ing 与 mpi isn't always safe or supported ,特别是对于使用 infiniband 互连运行的集群,但 OpenMPI 的 mpirun/mpiexec 会在不安全时警告您。

关于mpi 中的 Python 多处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25772289/

44 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com