我正在尝试使用多处理运行一个简单的测试。测试工作正常,直到我导入numpy(即使它没有在程序中使用)。这是代码:
from multiprocessing import Pool
import time
import numpy as np #this is the problematic line
def CostlyFunc(N):
""""""
tstart = time.time()
x = 0
for i in xrange(N):
for j in xrange(N):
if i % 2: x += 2
else: x -= 2
print "CostlyFunc : elapsed time %f s" % (time.time() - tstart)
return x
#serial application
ResultList0 = []
StartTime = time.time()
for i in xrange(3):
ResultList0.append(CostlyFunc(5000))
print "Elapsed time (serial) : ", time.time() - StartTime
#multiprocessing application
StartTime = time.time()
pool = Pool()
asyncResult = pool.map_async(CostlyFunc, [5000, 5000, 5000])
ResultList1 = asyncResult.get()
print "Elapsed time (multiporcessing) : ", time.time() - StartTime
如果我不导入numpy,结果是:
CostlyFunc : elapsed time 2.866265 s
CostlyFunc : elapsed time 2.793213 s
CostlyFunc : elapsed time 2.794936 s
Elapsed time (serial) : 8.45455098152
CostlyFunc : elapsed time 2.889815 s
CostlyFunc : elapsed time 2.891556 s
CostlyFunc : elapsed time 2.898898 s
Elapsed time (multiporcessing) : 2.91595196724
总耗用时间与1个进程所需的时间相似,这意味着计算已并行化。如果我导入numpy,结果将变为:
CostlyFunc : elapsed time 2.877116 s
CostlyFunc : elapsed time 2.866778 s
CostlyFunc : elapsed time 2.860894 s
Elapsed time (serial) : 8.60492110252
CostlyFunc : elapsed time 8.450145 s
CostlyFunc : elapsed time 8.473006 s
CostlyFunc : elapsed time 8.506402 s
Elapsed time (multiporcessing) : 8.55398178101
串行和多处理方法的总耗用时间相同,因为只使用了一个核心。很明显,问题来自于numpy。我的多处理版本和NumPy之间是否存在不兼容性?
我目前在linux上使用Python2.7,NumPy 1.6.2和多处理0.70a1
答案 0 :(得分:3)
(如果没有很好地制定或签署,首先发布对不起)
你可以通过将MKL_NUM_THREADS设置为1来阻止Numpy使用多线程
在debian下我用过:
export MKL_NUM_THREADS=1
来自相关stackoverflow帖子的来源:Python: How do you stop numpy from multithreading?
结果:
user@pc:~/tmp$ python multi.py
CostlyFunc : elapsed time 3.847009 s
CostlyFunc : elapsed time 3.253226 s
CostlyFunc : elapsed time 3.415734 s
Elapsed time (serial) : 10.5163660049
CostlyFunc : elapsed time 4.218424 s
CostlyFunc : elapsed time 5.252429 s
CostlyFunc : elapsed time 4.862513 s
Elapsed time (multiporcessing) : 9.11713695526
user@pc:~/tmp$ export MKL_NUM_THREADS=1
user@pc:~/tmp$ python multi.py
CostlyFunc : elapsed time 3.014677 s
CostlyFunc : elapsed time 3.102548 s
CostlyFunc : elapsed time 3.060915 s
Elapsed time (serial) : 9.17840886116
CostlyFunc : elapsed time 3.720322 s
CostlyFunc : elapsed time 3.950583 s
CostlyFunc : elapsed time 3.656165 s
Elapsed time (multiporcessing) : 7.399310112
我不确定这是否有帮助,因为我猜最终你想要numpy并行运行可能会尝试调整numpy到你的机器的线程数。
答案 1 :(得分:1)
根据您对问题的评论,请查看该链接 @Ophion没有,但我已将其标记为Why does multiprocessing use only a single core after I import numpy?的副本 - ali_m 8月22日9:06
我会检查您是否使用BLAS的优化版本。我发现numpy的一些通用安装不提供和优化此lib的版本。从我的安装中你可以注意到它指向libf77blas.so,libcblas.so,libatlas.so。
以下是构建优化版BLAS的说明:http://docs.scipy.org/doc/numpy/user/install.html
来自python:
导入numpy.core._dotblas
>>> numpy.core._dotblas.__file__
## output:
'PYTHONHOME/lib/python2.7/site-packages/numpy/core/_dotblas.so'
从您的终端:
$ ldd 'PYTHONHOME/lib/python2.7/site-packages/numpy/core/_dotblas.so'
linux-vdso.so.1 => (0x00007fff241ff000)
libf77blas.so => /opt/arch/intel/lib/libf77blas.so (0x00007f6050647000)
libcblas.so => /opt/arch/intel/lib/libcblas.so (0x00007f6050429000)
libatlas.so => /opt/arch/intel/lib/libatlas.so (0x00007f604fbf1000)
libpython2.7.so.1.0 => 'PYTHONHOME/lib/libpython2.7.so.1.0 (0x00007f604f817000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f604f5f9000)
libc.so.6 => /lib64/libc.so.6 (0x00007f604f266000)
libgfortran.so.3 => /usr/lib64/libgfortran.so.3 (0x00007f604ef74000)
libm.so.6 => /lib64/libm.so.6 (0x00007f604ecef000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f604eaeb000)
libutil.so.1 => /lib64/libutil.so.1 (0x00007f604e8e8000)
/lib64/ld-linux-x86-64.so.2(0x0000003c75e00000)