我已经在许多代码中成功使用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())
我要执行很多循环,并且真的希望/需要将它们拆分到多个内核上来提高速度。任何人都在思考为什么多处理反而会使我放慢速度,以及如何解决它?
答案 0 :(得分:3)
尽管np.correlate()
可以(并且您可能会这样做)release the GIL,但我认为您的数据太小,无法产生任何收益。也就是说,您的Python代码(循环)与GIL以及np.correlate()
的“序言”和“结语”部分(确实包含GIL)竞争。
您有一些选择可以改善并行度:
numba.jit(nogil=True)
来执行整个计算。但是那里只有一部分NumPy,我不认为其中包括np.correlate()
。multiprocessing.dummy
(使用线程)切换到multiprocessing
(使用进程,因此GIL没有争用)。np.correlate()
时都使用较大的数据。