随着维度增加,使用多进程进行Numpy矩阵乘法的速度突然变慢

4

我想使用 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()

由于所有 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

注意:我希望将并行计算用作复杂的内部模拟(类似于@),而不是将数据发送到子进程。

我想知道它是如何工作的!如果你在 import numpy as np 之前加入 print("foo") 作为第一行,它会被打印多少次? - aparpara
仅一次。foo - Seung Hyeon Yu
2
这可能与系统或硬件有关;也许是系统内存分页?我使用Python3.5,在Debian上获得了不同的输出 - Diane M
@SeungHyeonYu 我明白了,你正在使用Linux系统。在Windows系统下,每个进程都会导入主模块,因此你需要用 if __name__ == '__main__': 来保护它。 - aparpara
显示剩余8条评论
2个回答

1

这是给自己参考的。

这里,我找到了一个解决方案。

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

如果我运行以下代码:

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

在导入numpy之前出现了问题,然后解决了。

enter image description here


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接