使用进程和线程的mpi4py
你好,这个问题比较具体,希望StackOverflow能涵盖所有编程语言,而不仅仅是JavaScript或HTML。
我正在用MPICH2(一个流行的消息传递接口)写一个多程序。我的程序是用Python写的,所以我使用了MPI4Py这个Python库。MPI最适合没有共享内存的情况,因此不太适合多核编程。为了充分利用我5个节点集群中的4个核心,我还使用了线程。不过,我发现使用线程反而让我的模拟变得更慢。我的程序有几万行代码,不能全部贴出来,但这里有一段导致问题的代码。
from threading import Thread
...
threadIndeces=[[0,10],[11,20],[21,30],[31,40]] #subset for each thread
for indeces in treadIndeces:
t=Thread(target=foo,args=(indeces,))
t.start()
另外,我确保在后面会把线程合并。如果我不使用线程,直接用所有的索引调用foo
,速度大约快10到15倍。当我记录多线程版本的时间时,创建线程的那一行t=Thread(target=foo,args=(indeces,))
大约花了0.05秒,合并线程也差不多是0.05秒,但t.start()
的调用竟然要花0.2秒。
那么,start()
是一个耗时的调用吗?我应该改变我的方法吗?我考虑过保持一个线程池,而不是每次迭代都创建新的线程,但似乎t=Thread(target=foo,args=(indeces,))
并不是导致变慢的原因。
另外,如果有人想知道foo
的复杂性,这里有一个函数,它在每次迭代中会被调用i
次,针对indeces
(非离散时间):
def HD_training_firing_rate(HD_cell):
"""During training, the firing rate is governed by the difference between the
current heading direction and the preferred heading direction. This is made
to resemble a Gaussian distribution
"""
global fabs
global exp
global direction
#loop over twice due to concurrent CW and CCW HD training
for c in [0,1]:
d=direction[c]
dp=HD_cell.dp #directional preferance
s_d=20.0 #standard deviation
s_i=min(fabs(dp-d),360-fabs(dp-d)) #circular deviation from preferred dir.
HD_cell.r[c]=exp(-s_i*s_i/(2*s_d*s_d)) #normal distribution
1 个回答
如果你需要使用线程,Python可能不是最好的选择,因为它有一个叫做全局解释器锁的东西,这个锁会阻止真正的并发执行。你可以看看Dave Beazly的一个让人不安的演讲。
你可能更适合直接运行20个进程,这样可以让你的4个核心和5个节点都忙起来,然后用MPI来处理所有的通信。
在大型计算机上,Python的开销比较大——如果你真的想要使用线程和消息传递的方式,可能需要考虑用C或C++(或者我敢说Fortran?)来实现。