多处理与NumPy不兼容

时间:2013-08-07 14:11:21

标签: python numpy multiprocessing

我正在尝试使用多处理运行一个简单的测试。测试工作正常,直到我导入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

2 个答案:

答案 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)