使用多处理/线程将numpy数组操作分解为块

时间:2016-09-21 08:16:21

标签: python arrays multithreading multiprocessing

我有一个定义的函数,它呈现一个MxN数组。 该阵列非常庞大,因此我想使用该函数同时使用多处理/线程生成小型阵列(M1xN,M2xN,M3xN --- MixN。M1 + M2 + M3 + --- + Mi = M)并最终加入这些数组形成mxn数组。正如Boardrider先生正确地建议提供一个可行的例子,下面的例子将广泛传达我打算做的事情

import numpy as n
def mult(y,x):
    r = n.empty([len(y),len(x)])
    for i in range(len(r)):
        r[i] = y[i]*x
    return r
x = n.random.rand(10000)
y = n.arange(0,100000,1)
test = mult(y=y,x=x)

随着xy的长度增加,系统将花费越来越多的时间。关于这个例子,我想运行这个代码,如果我有4个核心,我可以给每个核心提供四分之一的工作,即计算元素r[0]r[24999]的工作到第1个核心,r[25000]r[49999]到第二核心,r[50000]r[74999]到第三核心,r[75000]r[99999]到第四核心。最终将结果添加到一起,将它们附加到r[0]r[99999]

我希望这个例子能说清楚。如果我的问题仍然不明确,请告诉我。

1 个答案:

答案 0 :(得分:7)

首先要说的是:如果它涉及同一处理器上的多个核心,numpy已经能够比我们手工做的更好地并行化操作(参见{ {3}})

在这种情况下,关键只是确保乘法全部在批量数组操作中完成而不是Python for - 循环:

test2 = x[n.newaxis, :] * y[:, n.newaxis]

n.abs( test - test2 ).max()  # verify equivalence to mult(): output should be 0.0, or very small reflecting floating-point precision limitations

[如果你真的想把它传播到多个独立的CPU上,这是另一回事,但问题似乎是建议使用单个(多核)CPU。]

好的,请注意以上几点:假设您希望并行化比mult()更复杂的操作。让我们假设您已经努力将您的操作优化为numpy可以并行化的批量阵列操作,但您的操作并不容易受此影响。在这种情况下,您可以使用由multiprocessing.Array创建的共享内存lock=Falsemultiprocessing.Pool来分配进程以解决非重叠的块,并在{{1}上进行划分维度(如果你愿意的话,也可以同时超过y)。下面提供了示例列表。请注意,此方法并未明确地执行您指定的操作(将结果组合在一起并将它们附加到单个数组中)。相反,它做了更有效的事情:多个进程同时在共享内存的非重叠部分中组合它们的部分答案。完成后,不需要整理/追加:我们只是读出结果。

x