【发布时间】:2015-03-31 01:02:41
【问题描述】:
我正在尝试在 Python 的 multiprocessing 模块的帮助下并行化一些使用 numpy 的计算。考虑这个简化的例子:
import time
import numpy
from multiprocessing import Pool
def test_func(i):
a = numpy.random.normal(size=1000000)
b = numpy.random.normal(size=1000000)
for i in range(2000):
a = a + b
b = a - b
a = a - b
return 1
t1 = time.time()
test_func(0)
single_time = time.time() - t1
print("Single time:", single_time)
n_par = 4
pool = Pool()
t1 = time.time()
results_async = [
pool.apply_async(test_func, [i])
for i in range(n_par)]
results = [r.get() for r in results_async]
multicore_time = time.time() - t1
print("Multicore time:", multicore_time)
print("Efficiency:", single_time / multicore_time)
当我执行它时,multicore_time 大致等于single_time * n_par,而我希望它接近single_time。事实上,如果我只用time.sleep(10) 替换numpy 计算,这就是我得到的——完美的效率。但由于某种原因,它不适用于numpy。这可以解决吗,还是numpy的一些内部限制?
一些可能有用的附加信息:
我使用的是 OSX 10.9.5、Python 3.4.2,CPU 是 Core i7,具有(根据系统信息报告)4 个内核(尽管上述程序总共只占用了 50% 的 CPU 时间,因此系统信息可能未考虑超线程)。
当我运行它时,我看到
top中的n_par进程以 100% 的 CPU 运行如果我用循环和按索引操作替换
numpy数组操作,效率会显着提高(n_par = 4提高到大约 75%)。
【问题讨论】:
-
你在做什么操作?在我的机器上,一些
numpy操作会在多核上自动执行。 -
主要是数组操作(没有
linalg的东西)。特别是,我不认为上面示例中的操作是并行的(至少当我运行test_func的单个实例时,我看不到它与top)。 -
@senderle:是的,我已经看到了这些问题。不幸的是,答案要么使用
taskset(在OSX 中不可用),要么设置一个MKL特定的环境变量(如果你不使用MKL,则不适用)。 -
P.S.另请参阅附加信息 #3:仅导入
numpy并不会造成太大影响。
标签: python numpy multiprocessing