17

我正在尝试使用多处理运行一个简单的测试。在我导入 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 个进程所需的时间,这意味着计算已并行化。如果我确实 import 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 和 multiprocessing 0.70a1

4

2 回答 2

4

(如果没有很好地制定或对齐,第一次发布很抱歉)

您可以通过将 MKL_NUM_THREADS 设置为 1 来停止 Numpy 使用多线程

在debian下我用过:

export MKL_NUM_THREADS=1

来自相关的stackoverflow帖子:Python:你如何阻止numpy进行多线程处理?

结果:

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 的线程数调整到您的机器上。

于 2013-10-04T16:59:13.950 回答
1

从您对问题的评论中,请查看@Ophion no 链接,但我已将其标记为为什么在我导入 numpy 后多处理仅使用单个核心?– ali_m 8 月 22 日 9:06

我会检查您是否使用了优化版本的 BLAS。我发现一些通用的 numpy 安装并没有提供这个库的优化版本。从我的安装中,您可以注意到它指向 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)

于 2013-11-28T17:50:21.430 回答