【问题标题】:How to parallelise loop in Python?如何在 Python 中并行化循环?
【发布时间】:2021-06-20 12:53:21
【问题描述】:

我希望在本地的多个处理器上运行我的程序中的瓶颈。我已经查看了multiprocessing,但对于我的目的来说它看起来有点复杂,我想知道是否有更简单的方法。

我有一个超过 360 个角度的循环,每个角度的计算都是独立的,所以它的执行顺序无关紧要。我有 8 个核心,所以希望我可以简单地将这个循环分成 8 个块45个角度并将它们发送到不同的核心并在最后收集结果。简化的示例如下所示:

dx = np.zeros(npixels)
for angle in range(360):
    dx += calculate_gradient_for_angle(angle, x, y, z, **kwargs)

这里,只有 angle 参数是可变的。其余的都是静态的。

我查看了multiprocessing.pool.Pool.map,但我只能找到显示传递给它的单参数函数的示例。如您所见,我的函数需要多个参数。任何指针将不胜感激。

我在 macOS 10.14.6 上使用 Python 3.7.8

【问题讨论】:

  • “但这只需要一个参数”什么?
  • 在任何情况下,利用多核的方法并不比使用multiprocessing 更复杂。话虽如此,很多 numpyscipy 代码可能已经在利用多个内核,因为它们正在调用本机二进制文件
  • 一个参数可以是一个元组、一个列表、一个范围、一个类实例,无论你需要什么
  • 您可以使用threading 轻松地将块分配给线程并让处理并行运行。
  • @juanpa.arrivillaga,我的意思是我能找到的所有示例都只是展示了如何将multiprocessing.pool.Pool.map 与一个本身带有一个参数的函数一起使用。我已经修改了我的帖子。查看我的程序运行时的 CPU 负载,我怀疑 numpy 是否使用了多个内核。

标签: python parallel-processing python-multiprocessing


【解决方案1】:

你可以构建这样的东西。我是从this question 那里得到这个想法的。

import concurrent.futures

def foo(bar):
    return bar

# Start each calculation in a seperate thread
with concurrent.futures.ThreadPoolExecutor() as ex:
    f = [ex.submit(foo, angle) for angle in range(10)]

dx = 0

# Collect all results
for r in f:
  dx += r.result()

print(dx)

【讨论】:

    【解决方案2】:

    简单的解决方案是使用functools.partial 将函数转换为单参数函数并将其传递给multiprocessing.pool.Pool.map,如下所示:

    from functools import partial
    import multiprocessing as mp
    
    calculate_grad_partial = partial(calculate_grad_for_angle, x=x, y=y, z=z)
    
    with mp.Pool(processes=8) as pool:
        dx = pool.map(calculate_grad_partial, range(360))
    

    【讨论】:

      猜你喜欢
      • 2013-09-02
      • 2017-03-17
      • 2020-09-14
      • 1970-01-01
      • 1970-01-01
      • 2019-01-12
      相关资源
      最近更新 更多