Python 带有进程和线程的mpi4py

Python 带有进程和线程的mpi4py,python,multithreading,mpi,Python,Multithreading,Mpi,您好,这是一个非常具体的问题,所以我希望StackOverflow适用于所有编程语言,而不仅仅是javascript/html 我正在用MPICH2(流行的消息传递接口)编写一个多程序。我的程序是用Python编写的,所以我使用MPI4Py Python绑定。MPI最适合没有共享内存的情况,因此,它不适合多核编程。为了使用我的5节点集群的全部4个核心,我进一步使用了线程。然而,我注意到使用线程实际上会减慢我的模拟速度。我的程序有好几万行代码,所以我不能把它们全部放上去,但下面是引起问题的代码片段

您好,这是一个非常具体的问题,所以我希望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
次:


如果您需要线程,python可能不是您的最佳选择,因为它会阻止真正的并发。另见

您最好只运行20个进程,让4个核心和5个节点保持忙碌,并且只使用MPI进行所有通信


< Python在大铁上会产生大量开销——如果你真的致力于一个联合线程/消息传递方法,你可能会想C或C++(或者我敢说Fortran?)。

+ 1——我不确定这里的线程有什么优势。看起来每个线程都在做完全独立的事情?如果是这样,那么使用线程比使用MPI有什么好处?就发现性能问题而言,最好从等式中去掉更大规模的分解,然后集中精力让事情尽可能快地在一个共享内存盒上运行,然后重新引入跨节点MPI。如果你一直坚持用python来完成整个工作,你可能最终会发现基于进程的方法(如多处理)的性能优于线程。@Drew Hall:我最初使用的是C语言,但这种语言非常乏味,python更易于使用。@Drew Hall,Jonathan Dursi:人们似乎忘记了MPI假设没有共享内存,而线程允许共享内存。这里的问题是全局变量。我做了很多缩放,这需要计算全局最大值。使用线程可以很容易地实现这一点,事实上这是微不足道的。如果我使用MPI并在单个节点上运行多个进程,那么它们将必须通信这些全局最大值。请原谅我的语言,交流是一种痛苦。@puk:即使有多个进程,您也应该能够为同一节点上的进程打开共享内存段。我不知道如何在python中做到这一点,但如果做不到,我会感到惊讶。@Drew Hall:我只是想指出为什么我选择在MPI之外使用线程。我不是100%确定,但我99%确定一个人不能通过MPI共享内存。
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