使用Scipy进行大卷积的多处理无法加速

时间:2019-02-27 20:20:41

标签: python numpy parallel-processing scipy multiprocessing

我正在使用<form action="/create_cf/" method="post"> {% csrf_token %} {{cf}} <input type="submit" value="Submit"> </form> 执行大型2D卷积。我有很多要处理的数组,因此很自然地认为scipy.signal.correlate会有所帮助。但是,使用以下简单设置(在4核cpu上)没有好处。

multiprocessing.Pool

将进程计数更改为{1、2、3、4}大约需要相同的时间(2.6秒+-.2)。

会发生什么?

2 个答案:

答案 0 :(得分:2)

  

怎么回事?

首先,我认为原因是基础FFT实现已经并行化。尽管Python解释器是单线程的,但可以从Python调用的C代码可能能够充分利用您的CPU。

但是,scipy.correlate的基础FFT实现似乎是NumPy中的fftpack(从1985年编写的Fortran进行翻译而来),它似乎是fftpack page上的单线程。 >

的确,我运行了您的脚本并获得了更高的CPU使用率。在我的计算机上有四个内核并且有四个进程的情况下,我的速度提高了约2(对于2000x2000阵列,并使用了Raw Dawg中的代码更改)。

创建进程和与进程进行通信所产生的开销吞噬了CPU使用效率提高的部分好处。

您仍然可以尝试优化数组大小或仅计算一小部分相关性(如果不需要全部),或者如果内核始终相同,则仅计算内核的FFT一次并重用它(这需要实现scipy.correlate的一部分),或者尝试单精度而不是双精度,或者使用CUDA在图形卡上进行关联。

答案 1 :(得分:2)

我认为问题出在这一行:

StackedAreaRenderer

Pool.apply是一项阻塞操作,在数组中的每个元素上运行results = [pool.apply(conv, args=(arr, kernel)) for arr in arrays],然后等待下一个元素,因此,即使看起来像是多处理,实际上也没有任何分配。您需要使用pool.map来获取您想要的行为:

conv