【问题标题】:Python - Multi processing to mount an arrayPython - 多处理以挂载数组
【发布时间】:2015-04-21 08:49:00
【问题描述】:

我正在使用 griddata 来“挂载”具有大量形状和 我想知道我是否可以在每个 4 个内核上计算函数(在每个切片上)以加速该过程?

import numpy

size = 8.
Y=(arange(2000))
X=(arange(2000))
(xx,yy)=meshgrid(X,Y)

array=zeros((Y.shape[0],X.shape[0],size))

array[:,:,0] = 0
array[:,:,1] = X+Y
array[:,:,2] = X**2+Y**2+X+Y
array[:,:,3] = X**3+Y**3+X**2+Y**2+X+Y

array[:,:,4] = X**4+Y**4+X**3+Y**3+X**2+Y**2+X+Y
array[:,:,5] = X**5+Y**5+X**4+Y**4+X**3+Y**3+X**2+Y**2+X+Y
array[:,:,6] = X**6+Y**6+X**5+Y**5+X**4+Y**4+X**3+Y**3+X**2+Y**2+X+Y
array[:,:,6] = X**7+Y**7+X**6+Y**6+X**5+Y**5+X**4+Y**4+X**3+Y**3+X**2+Y**2+X+Y

所以在这里我想用第一个核心计算 array[:,:,0] & array[:,:,1],然后 array[:,:,2] & array[:,:,3]用第二个核心...?

----稍后编辑---

不同“切片”之间没有联系……我的不同功能是独立的

array[:,:,0] = 0
array[:,:,1] = X+Y
array[:,:,2] = X*np.cos(X)+Y*np.sin(Y)
array[:,:,3] = X**3+np.sin(X)+X**2+Y**2+np.sin(Y)
...

【问题讨论】:

    标签: python arrays numpy multiprocessing


    【解决方案1】:

    你可以试试multiprocessing.Pool

    from multiprocessing import Pool
    import numpy as np
    
    size = 8.
    Y=(np.arange(2000))
    X=(np.arange(2000))
    (xx,yy)=np.meshgrid(X,Y)
    
    array=np.zeros((Y.shape[0],X.shape[0],size))
    
    def func(i): # you need to call a function with Pool
        array_=np.zeros((Y.shape[0],X.shape[0]))
        for j in range(1,i):
            array_+=X**j+Y**j
        return array_
    
    if __name__ == '__main__':
        p = Pool(4) # if you have 4 cores in your processor
        result=p.map(func, range(1,8))
        for i in range(1,8):
            array[::,::,i]=result[i-1]
    

    请记住,python 中的多处理共享内存,这就是为什么您必须创建 array_ 并在代码末尾添加 for 循环的原因。 由于您的应用程序(具有这些维度)不需要大量计算时间,因此使用此方法可能会变慢。您还将创建所有变量的多个副本,这可能会导致内存溢出。 您还应该仔细检查我写的func,因为我没有完全验证它是否做了它应该做的事情:)

    【讨论】:

    • 对不起,在我的情况下,我的函数之间没有链接......所以我不能写:“for j in range(1,i): array_+=Xj+Y j"
    • 然后你可以为每个函数使用multiprocessing.Process:它将为你的数组的每个维度启动一个独立的(仍然没有共享内存)进程,你将不得不重新构建你的数组(正如我所做的那样)例如通过使用队列收集各种返回。如果您对不同的数组大量使用相同的函数,那么这项工作可能是值得的。如果您认为它可以工作,我可以帮助您编写多处理部分的代码。
    • 感谢您的帮助,但是当我计算有和没有多进程的时间时......我发现没有多进程我更快:s –
    • 在您的情况下,是的,很有可能。 Python中的多处理对于应该同时运行的长任务和重复任务非常有用,而不是小任务。正如@Mr E 所说,现在改善执行时间的唯一方法是简化数学并将计算分组。
    【解决方案2】:

    如果您想对数据数组应用单个函数,则使用例如multiprocessing.Pool 是一个很好的解决方案,假设计算的输入和输出都比较小。

    您想对两个输入数组执行许多不同的计算,这会导致为每个计算返回一个数组。

    由于单独的进程不共享内存,因此必须在启动时将 X 和 Y 数组传输到每个工作进程。并且每次计算的结果(也是一个与 X 和 Y 大小相同的 numpy 数组)必须返回给父进程。

    取决于例如数组的大小和内核的数量,通过进程间通信(“IPC”)在工作进程和父进程之间传输所有这些数组的开销将花费时间,减少 使用多核的优势。

    请记住,父进程必须侦听和处理来自所有工作进程的 IPC 请求。所以你已经将瓶颈从计算转移到通信

    因此,在这种情况下,多处理实际上不会提高性能。这取决于实际问题的细节(核心数量、阵列大小、物理内存量等)。

    您必须使用例如PoolProcess 具有真实的数组大小。

    【讨论】:

      【解决方案3】:

      三件事:

      1. 最重要的问题是why are you doing this?
      2. 您的 NumPy 构建可能已经在使用多个内核。我不确定如何检查,see questions like this如果绝对必要看看 Numexpr 库https://github.com/pydata/numexpr
      3. 关于您可能出现的 XY 问题中的“Y” - 您正在重新计算可以重新使用的数据:

      .

      import numpy
      
      size = 8
      Y=(arange(2000))
      X=(arange(2000))
      (xx,yy)=meshgrid(X,Y)
      
      array = zeros((Y.shape[0], X.shape[0], size))
      
      array[..., 0] = 0    
      for i in range(1, size):
          array[..., 1] = X ** i + Y ** i + array[..., i - 1]
      

      【讨论】:

      • 第三点只是一个例子,我不能重复使用计算。
      • 在这种情况下,请询问您的实际问题
      • 我的意思是我的不同功能之间没有联系。
      • 你应该检查第二点。 Numpy 确实在大量使用多处理。尝试使用 Numpy 函数计算您需要的内容。在 ubuntu 中,您可以使用 htop 查看您的处理器活动,在 windows 中使用任务管理器。
      • @MrE 根据所使用的 BLAS 库,numpy.dot 之类的内容可能会被并行化。如果import numpy.core._dotblas 成功,那么你就有了一个快速的 BLAS 实现。
      猜你喜欢
      • 2012-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-27
      • 1970-01-01
      • 2013-02-25
      • 1970-01-01
      相关资源
      最近更新 更多