多处理会使我的代码变慢而不是加快速度

时间:2019-03-02 12:27:30

标签: python numpy multiprocessing

我已经在许多代码中成功使用multiprocessing.dummy.Pool来加快循环的计算时间。但是我遇到了一个我无法弄清楚的问题,我添加的线程越多,代码运行的速度就越慢。这一切都在python 2.7中完成,并在8核windoze盒上运行。

import numpy as np
from multiprocessing.dummy import Pool 
from datetime import datetime
global X

pool=Pool(processes=1)

def foo(iy):
    global X
    x=X[iy]
    for i in range(len(x)):
        for j in range(len(x[i])):
            _=np.correlate(x[i,j],[1,1,1],mode='same')
    return None

t=datetime.now()
X=np.random.rand(11,11,512,512)
_=pool.map(foo,range(11))
print((datetime.now()-t).total_seconds())

使用processes=1,运行时间为0.7秒。如果使用processes=2,则增加到1秒;如果使用processes=4,则增加到2.3秒。如果我按如下所示重写代码,则会发生相同的问题:

import numpy as np
from multiprocessing.dummy import Pool 
from datetime import datetime

pool=Pool(processes=1)

def foo(x):
    for i in range(len(x)):
        for j in range(len(x[i])):
            _=np.correlate(x[i,j],[1,1,1],mode='same')
    return None

t=datetime.now()
X=np.random.rand(11,11,512,512)
_=pool.map(lambda z:foo(X[z]),range(11))
print((datetime.now()-t).total_seconds())

我要执行很多循环,并且真的希望/需要将它们拆分到多个内核上来提高速度。任何人都在思考为什么多处理反而会使我放慢速度,以及如何解决它?

1 个答案:

答案 0 :(得分:3)

尽管np.correlate()可以(并且您可能会这样做)release the GIL,但我认为您的数据太小,无法产生任何收益。也就是说,您的Python代码(循环)与GIL以及np.correlate()的“序言”和“结语”部分(确实包含GIL)竞争。

您有一些选择可以改善并行度:

  1. 使用numba.jit(nogil=True)来执行整个计算。但是那里只有一部分NumPy,我不认为其中包括np.correlate()
  2. 使用其他语言(例如Cython或C)来实现计算,并在计算时释放GIL。
  3. multiprocessing.dummy(使用线程)切换到multiprocessing(使用进程,因此GIL没有争用)。
  4. 每次调用np.correlate()时都使用较大的数据。