mpi中的Python多处理

2024-04-24 04:18:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个使用多处理模块编写的python脚本,用于更快的执行。计算是令人难堪的并行,因此效率随处理器数量而变化。现在,我想在一个MPI程序中使用它,该程序管理跨多台计算机的MCMC计算。这段代码调用了调用python脚本的system()。然而,我发现当这样调用它时,使用python多处理所获得的效率增益将消失。

当从MPI调用python脚本时,如何让它保持从多处理中获得的速度增益?

下面是一个简单的例子,它类似于我想要使用的更复杂的代码,但是显示了相同的一般行为。我编写了一个名为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,总的来说运行时间大约是mpirun的三倍。使用-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版本的MPIRun1.8.1,Python2.7.3 wheezy。我听说在MPI程序中不允许使用system(),但在过去的五年里,它一直在这台计算机上为我工作。例如,我从MPI程序中的system()调用了一个基于pthread的并行代码,并且根据需要,它为每个线程使用了100%的cpu。另外,如果您打算建议以串行方式运行python脚本,并在更多节点上调用它……MCMC计算涉及固定数量的链,这些链需要以同步方式移动,因此很遗憾,计算不能以这种方式重新组织。)


Tags: 代码py程序脚本bin进程usrnp
1条回答
网友
1楼 · 发布于 2024-04-24 04:18:38

OpenMPI's mpirun, v1.7 and later,默认为将进程绑定到核心,也就是说,当它启动python junk.py进程时,它将它绑定到它将运行的核心。这很好,对于大多数MPI用例来说都是正确的默认行为。但是在这里,每个MPI任务都会派生出更多的进程(通过多处理包),而这些派生进程继承了其父进程的绑定状态,因此它们都绑定到同一个核心,彼此争斗。(顶部的“P”列将显示它们都在同一个处理器上)

如果您使用mpirun-np 2,您将发现两组由三个进程组成的进程,每个进程位于不同的核心上,每个进程在它们之间竞争。

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

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

或者选择一些其他绑定,考虑到您的最终运行几何体,这是有意义的。MPICH有similar options with hydra

注意,使用mpi isn't always safe or supported的子进程的fork()操作,特别是使用infiniband互连运行的集群,但是OpenMPI的mpirun/mpiexec会警告您它是否安全。

相关问题 更多 >