随着尺寸的增加,带有多处理的Numpy矩阵乘法突然减慢

时间:2019-04-19 07:56:29

标签: python numpy multiprocessing

我想用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都是相同的,因此并行处理时间应相等。

但实际输出不是。

enter image description here

系统信息:

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
  

注意,我想将并行计算用作复杂的内部模拟(例如@),而不是将数据发送到子进程。

2 个答案:

答案 0 :(得分:0)

这仅供参考。

Here,我找到了解决方法。

我的numpy使用MKL作为后端,这可能是MKL多线程冲突multiprocessing的问题。

如果我运行代码:

import os
os.environ['MKL_NUM_THREADS'] = '1'

在导入numpy之前,它就解决了。

enter image description here

答案 1 :(得分:0)

我在这里找到了一个解释:https://github.com/numpy/numpy/issues/10145。 当您同时发生冲突的MKL矩阵乘法时,看起来CPU缓存混乱了。