【发布时间】:2012-10-15 15:31:24
【问题描述】:
我知道关于这个主题的几个问题和答案,但还没有找到对这个特定问题的满意答案:
在通过 numpy/scipy 函数操作 numpy 数组的 python 循环中进行简单的共享内存并行化的最简单方法是什么?
我不是在寻找最有效的方法,我只是想要一些简单的实现方式,当循环不并行运行时不需要大量重写。就像 OpenMP 在低级语言中实现一样。
我在这方面看到的最佳答案是this one,但这是一种相当笨拙的方式,需要将循环表达为一个函数,该函数接受一个参数,几行共享数组转换crud,似乎需要从__main__ 调用并行函数,并且从交互式提示(我花了很多时间)似乎不能很好地工作。
Python 的所有简单性真的是并行化循环的最佳方式吗?真的吗?这对于以 OpenMP 方式进行并行化来说是微不足道的。
我煞费苦心地阅读了多处理模块的不透明文档,却发现它是如此通用,以至于它似乎适用于除了简单的循环并行化之外的所有东西。我对设置管理器、代理、管道等不感兴趣。我只有一个简单的循环,完全并行,任务之间没有任何通信。使用 MPI 并行化这样一个简单的情况似乎有点过头了,更不用说在这种情况下内存效率低了。
我还没有时间了解用于 Python 的大量不同的共享内存并行包,但想知道是否有人在这方面有更多经验并且可以告诉我一个更简单的方法。请不要建议使用 Cython 之类的串行优化技术(我已经使用它),或使用 BLAS 之类的并行 numpy/scipy 函数(我的情况更通用,更并行)。
【问题讨论】:
-
相关:OpenMP and Python。请参阅我的答案中的示例。
-
在 Linux 上,您链接到的答案中的代码可以在交互式提示中正常工作。此外,Cython 确实支持基于 openmp 的并行化,而且使用起来非常简单(在循环中将
range替换为prange):docs.cython.org/src/userguide/parallelism.html -
@pv,感谢您的链接。它看起来很简单。但我假设 prange 只能用于 C 函数?这带来了其他问题,例如在 Cython 内部使用 numpy/scipy 数组函数。我不认为有一个简单的接口可以在 Cython 中使用这些函数的 C 等价物?
-
OpenMP 通常用于紧密循环的细粒度并行性。您在 python 中找不到任何等价物的原因是因为 python 没有为紧密循环提供良好的性能。如果您不需要紧密循环,请使用多处理模块。如果你这样做,那么按照建议使用 cython。
-
@tiago:您可以将 prange 循环包装在
with nogil:中以使用任何 Python 结构。一些 Numpy 函数在操作过程中会释放 GIL,因此您可能会获得一些并行性。但是,对 Python 对象的访问始终是序列化的,因此线程不可避免地会部分同步。这与 Python 在单个进程中的并行性一样好——您需要使用多处理来获得更多。
标签: python numpy parallel-processing multiprocessing shared-memory