Ray*_*let 13 python mpi multiprocessing
我有一个使用多处理模块编写的python脚本,以便更快地执行.计算是令人尴尬的并行,因此效率随着处理器的数量而变化.现在,我想在MPI程序中使用它,该程序管理跨多台计算机的MCMC计算.此代码调用system()来调用python脚本.但是,我发现当它以这种方式调用时,使用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()
Run Code Online (Sandbox Code Playgroud)
当我自己从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
Run Code Online (Sandbox Code Playgroud)
但是,如果我用mpirun调用它,每个python进程占用cpu的33%,总体而言,它需要大约三倍的运行时间.使用-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
Run Code Online (Sandbox Code Playgroud)
(补充说明:这是mpirun 1.8.1,Linux Debian版本的python 2.7.3喘息.我听说系统()并不总是允许在MPI程序中,但它在这台计算机上已经为我工作了五年.例如,我在MPI程序中调用了来自system()的基于pthread的并行代码,并且根据需要使用100%的cpu作为每个线程.另外,如果你打算建议在串行中运行python脚本,只是在更多节点上调用它... MCMC计算涉及需要以同步方式移动的固定数量的链,因此遗憾的是,计算不能以这种方式重组.)
Jon*_*rsi 11
OpenMPI的mpirun,v1.7及更高版本,默认将进程绑定到核心 - 也就是说,当它启动python junk.py进程时,它会将它绑定到它将运行的核心.这很好,并且是大多数MPI用例的正确默认行为.但是这里每个MPI任务都会分支更多进程(通过多处理包),并且那些分叉进程继承其父进程的绑定状态 - 所以它们都绑定到同一个核心,在它们之间进行斗争.(顶部的"P"列将显示它们都在同一个处理器上)
如果你mpirun -np 2,你会发现两组三个进程,每个进程在不同的核心上,每个进程在它们之间竞争.
使用OpenMPI,您可以通过关闭绑定来避免这种情况,
mpirun -np 1 --bind-to none junk.py
Run Code Online (Sandbox Code Playgroud)
或者选择其他一些在运行的最终几何形状下有意义的绑定.MPICH 与hydra有类似的选择.
请注意,带有mpi的子进程的fork()并不总是安全或受支持,特别是对于使用infiniband互连运行的集群,但OpenMPI的mpirun/mpiexec会在不安全的情况下发出警告.
| 归档时间: |
|
| 查看次数: |
6122 次 |
| 最近记录: |