我想用multiprocessing.Pool
做一些大矩阵乘法。
突然,当尺寸大于50时,将花费极长的计算时间。
有没有简单的方法可以更快?
在这里,我不想使用RawArray
之类的共享内存,因为我的原始代码每次都会随机生成矩阵。
示例代码如下。
import numpy as np
from time import time
from multiprocessing import Pool
from functools import partial
def f(d):
a = int(10*d)
N = int(10000/d)
for _ in range(N):
X = np.random.randn(a,10) @ np.random.randn(10,10)
return X
# Dimensions
ds = [1,2,3,4,5,6,8,10,20,35,40,45,50,60,62,64,66,68,70,80,90,100]
# Serial processing
serial = []
for d in ds:
t1 = time()
for i in range(20):
f(d)
serial.append(time()-t1)
# Parallel processing
parallel = []
for d in ds:
t1 = time()
pool = Pool()
for i in range(20):
pool.apply_async(partial(f,d), args=())
pool.close()
pool.join()
parallel.append(time()-t1)
# Plot
import matplotlib.pyplot as plt
plt.title('Matrix multiplication time with 10000/d repetitions')
plt.plot(ds,serial,label='serial')
plt.plot(ds,parallel,label='parallel')
plt.xlabel('d (dimension)')
plt.ylabel('Total time (sec)')
plt.legend()
plt.show()
由于f(d)
的总计算成本对于所有d
都是相同的,因此并行处理时间应相等。
但实际输出不是。
系统信息:
Linux-4.15.0-47-generic-x86_64-with-debian-stretch-sid
3.6.8 |Anaconda custom (64-bit)| (default, Dec 30 2018, 01:22:34)
[GCC 7.3.0]
Intel(R) Core(TM) i9-7940X CPU @ 3.10GHz
注意,我想将并行计算用作复杂的内部模拟(例如
@
),而不是将数据发送到子进程。
答案 0 :(得分:0)
这仅供参考。
Here,我找到了解决方法。
我的numpy
使用MKL作为后端,这可能是MKL多线程冲突multiprocessing
的问题。
如果我运行代码:
import os
os.environ['MKL_NUM_THREADS'] = '1'
在导入numpy
之前,它就解决了。
答案 1 :(得分:0)
我在这里找到了一个解释:https://github.com/numpy/numpy/issues/10145。 当您同时发生冲突的MKL矩阵乘法时,看起来CPU缓存混乱了。