为什么当我试图在 python 中将我的程序加速 multiprocess.Pool 时,多进程比单进程慢?
Why multiple process is slower than single when I'm trying to accelerate my program by multiprocess.Pool in python?
我知道很多人问过类似的问题。但是我找不到任何东西可以解释这种现象。这是我的代码。
import time
from multiprocessing import Pool
import numpy as np
def _foo(x):
np.linalg.inv(x)
if __name__ == '__main__':
t = time.time()
r = np.random.rand(1000, 1000)
p = Pool(2)
p.map(_foo, [r.copy() for i in range(8)])
print 'Finished in', time.time() - t, 'sec'
当我使用其他耗时的操作来测试我的代码而不是np.linalg.inv
。它工作正常。随着 Pool
大小的增加,我确实获得了性能提升。但是,当我在函数 _foo
中使用 np.linalg.inv
时,Pool(2)
比 Pool(1)
慢得多。 Pool(1)
为 0.77,Pool(2)
为 9.84。该代码在具有 6 个物理核心的机器上进行了测试。
我能推断的唯一解释是 inv
方法共享一些资源。但是我已经为每个进程复制了 r
。看来没必要了
我终于明白了。它是在 Ubuntu 上使用 openBLAS 构建的 "bug" numpy。从 Unbuntu 12.04 开始,openBLAS 变成了多线程。所以当我开始两个处理来加速我的计算时,实际上有 24 个线程 运行ning 在 6 个物理内核上。这是一个典型的开销问题。
我的解决方法是设置环境变量OPENBLAS_NUM_THREADS=1。这会在单线程模式下强制 openBLAS 运行。
我知道很多人问过类似的问题。但是我找不到任何东西可以解释这种现象。这是我的代码。
import time
from multiprocessing import Pool
import numpy as np
def _foo(x):
np.linalg.inv(x)
if __name__ == '__main__':
t = time.time()
r = np.random.rand(1000, 1000)
p = Pool(2)
p.map(_foo, [r.copy() for i in range(8)])
print 'Finished in', time.time() - t, 'sec'
当我使用其他耗时的操作来测试我的代码而不是np.linalg.inv
。它工作正常。随着 Pool
大小的增加,我确实获得了性能提升。但是,当我在函数 _foo
中使用 np.linalg.inv
时,Pool(2)
比 Pool(1)
慢得多。 Pool(1)
为 0.77,Pool(2)
为 9.84。该代码在具有 6 个物理核心的机器上进行了测试。
我能推断的唯一解释是 inv
方法共享一些资源。但是我已经为每个进程复制了 r
。看来没必要了
我终于明白了。它是在 Ubuntu 上使用 openBLAS 构建的 "bug" numpy。从 Unbuntu 12.04 开始,openBLAS 变成了多线程。所以当我开始两个处理来加速我的计算时,实际上有 24 个线程 运行ning 在 6 个物理内核上。这是一个典型的开销问题。
我的解决方法是设置环境变量OPENBLAS_NUM_THREADS=1。这会在单线程模式下强制 openBLAS 运行。