我知道关于这个问题有几个问题和答案,但还没有找到一个令人满意的答案:
对于通过numpy/scipy函数操作numpy数组的python循环,最简单的方法是什么?
我并不是在寻找最有效的方法,我只是想实现一些简单的东西,当循环不并行运行时,不需要进行重要的重写。就像OpenMP在低级语言中实现一样。
在这方面,我看到的最好的答案是this one,但这是一种相当笨拙的方法,它需要将循环表示为一个函数,该函数只接受一个参数,几行共享数组转换crud,似乎需要从__main__
调用并行函数,从交互提示(我花了很多时间)来看,它似乎不太好用。
使用Python的所有简单性,这真的是并行化循环的最佳方法吗?真正地?在OpenMP方式中,这是一件很容易并行的事情。
我仔细阅读了多处理模块的不透明文档,结果发现它非常通用,除了简单的循环并行化之外,似乎什么都适合。我对设置管理器、代理、管道等不感兴趣。我只是有一个简单的循环,完全并行,任务之间没有任何通信。使用MPI来并行处理这样一个简单的情况似乎有点过头了,更不用说在这种情况下会导致内存效率低下。
我还没来得及了解Python的许多不同的共享内存并行包,但我想知道是否有人在这方面有更多的经验,并且可以向我展示一种更简单的方法。请不要推荐串行优化技术,如Cython(我已经在使用它),或者使用并行numpy/scipy函数,如BLAS(我的例子更通用,也更并行)。
在ParallelRegression中mathDict()类的.map( )方法在两行代码中所做的正是您所寻找的,在交互提示下应该非常容易。它使用真正的多处理,因此要求并行运行的函数是可pickle的,这是不可避免的,但这确实提供了一种简单的方法,可以从多个进程循环共享内存中的矩阵。
假设你有一个泡菜功能:
然后您只需要创建一个表示它的mathDict()对象,并使用mathDict().map():
文档(上面的链接)解释了如何将位置参数和关键字参数的组合传递到函数中,包括任何位置的矩阵本身或作为关键字参数传递。这将使您能够使用几乎所有已编写的函数,而无需修改它。
带Cython平行支架:
在双核心机器上:
这可以并行运行,因为
np.cos
(与其他ufunc一样)会释放GIL。如果要交互使用此选项:
并且(首先删除
asd.so
和asd.c
):所以是的,在某些情况下,您可以通过使用线程来并行化。OpenMP只是一个很好的线程包装器,因此这里只需要Cython来实现更简单的语法。如果没有Cython,您可以使用
threading
模块,它的工作方式与多处理类似(可能更可靠),但是您不需要做任何特殊的事情来声明数组为共享内存。不过,并不是所有的操作都会发布GIL,所以YMMV是为了性能。
另一个可能有用的链接是从其他Stackoverflow答案中刮来的——另一个到多处理的接口:http://packages.python.org/joblib/parallel.html
使用映射操作(在本例中是
multiprocessing.Pool.map()
)或多或少是在单个计算机上并行化循环的规范方法。除非和直到内置的map()
被并行化。对不同可能性的概述可以在here中找到。
您可以使用openmp with python(或者更确切地说是cython),但看起来并不简单。
IIRC,如果只运行
__main__
中的多处理内容,这一点是必要的,因为它与Windows兼容。由于windows缺少fork()
,它将启动一个新的python解释器,并必须导入其中的代码。编辑
Numpy可以并行化一些操作,比如
dot()
、vdot()
和innerproduct()
,如果配置了一个好的多线程BLAS库,比如OpenBLAS。(另请参见this question。)由于numpy数组操作主要是按元素进行的,因此似乎可以将它们并行化。但这将涉及为python对象设置一个共享内存段,或者将数组分成多个部分并将它们提供给不同的进程,这与
multiprocessing.Pool
所做的工作没有什么不同。不管采取什么方法,管理所有这些都会产生内存和处理开销。我们将不得不运行大量的测试,看看这对于哪些大小的数组是值得的。这些测试的结果可能会因硬件架构、操作系统和RAM数量的不同而有很大差异。相关问题 更多 >
编程相关推荐