gpt4 book ai didi

python - 使用 numpy 数组和共享内存并行化 python 循环

转载 作者:IT老高 更新时间:2023-10-28 20:29:00 24 4
gpt4 key购买 nike

我知道有关此主题的几个问题和答案,但尚未找到对此特定问题的满意答案:

在通过 numpy/scipy 函数操作 numpy 数组的 python 循环中进行简单的共享内存并行化的最简单方法是什么?

我不是在寻找最有效的方法,我只是想要一些简单的实现方式,当循环不并行运行时不需要大量重写。就像 OpenMP 在低级语言中实现一样。

我在这方面看到的最佳答案是this one , 但这是一种相当笨拙的方式,需要将循环表达为一个接受单个参数的函数,几行共享数组转换 crud,似乎需要从 __main__ 调用并行函数>,并且从交互式提示(我花了很多时间)看来效果不佳。

Python 的所有简单性真的是并行化循环的最佳方式吗?真的吗?这对于以 OpenMP 方式进行并行化来说是微不足道的。

我煞费苦心地阅读了多处理模块的不透明文档,却发现它是如此通用,以至于它似乎适用于除了简单的循环并行化之外的所有东西。我对设置管理器、代理、管道等不感兴趣。我只有一个简单的循环,完全并行,任务之间没有任何通信。使用 MPI 并行化这样一个简单的情况似乎有点过头了,更不用说在这种情况下内存效率低了。

我还没有时间了解用于 Python 的大量不同的共享内存并行包,但想知道是否有人在这方面有更多经验并且可以告诉我一个更简单的方法。请不要建议使用 Cython 等串行优化技术(我已经使用它),或使用 BLAS 等并行 numpy/scipy 函数(我的情况更通用,更并行)。

最佳答案

使用 Cython 并行支持:

# asd.pyx
from cython.parallel cimport prange

import numpy as np

def foo():
cdef int i, j, n

x = np.zeros((200, 2000), float)

n = x.shape[0]
for i in prange(n, nogil=True):
with gil:
for j in range(100):
x[i,:] = np.cos(x[i,:])

return x

在 2 核机器上:

$ cython asd.pyx
$ gcc -fPIC -fopenmp -shared -o asd.so asd.c -I/usr/include/python2.7
$ export OMP_NUM_THREADS=1
$ time python -c 'import asd; asd.foo()'
real 0m1.548s
user 0m1.442s
sys 0m0.061s

$ export OMP_NUM_THREADS=2
$ time python -c 'import asd; asd.foo()'
real 0m0.602s
user 0m0.826s
sys 0m0.075s

这可以并行运行,因为 np.cos(与其他 ufunc 一样)释放 GIL。

如果您想以交互方式使用它:

# asd.pyxbdl
def make_ext(modname, pyxfilename):
from distutils.extension import Extension
return Extension(name=modname,
sources=[pyxfilename],
extra_link_args=['-fopenmp'],
extra_compile_args=['-fopenmp'])

and(先去掉asd.soasd.c):

>>> import pyximport
>>> pyximport.install(reload_support=True)
>>> import asd
>>> q1 = asd.foo()
# Go to an editor and change asd.pyx
>>> reload(asd)
>>> q2 = asd.foo()

所以是的,在某些情况下,您可以仅使用线程进行并行化。 OpenMP 只是一个花哨的线程包装器,因此这里只需要 Cython 以实现更简单的语法。如果没有 Cython,您可以使用 threading 模块 --- 与多处理类似(并且可能更健壮),但您无需执行任何特殊操作即可将数组声明为共享内存。

然而,并不是所有的操作都会释放 GIL,所以 YMMV 对于性能来说。

***

从其他 Stackoverflow 答案中提取的另一个可能有用的链接 --- 另一个多处理接口(interface):http://packages.python.org/joblib/parallel.html

关于python - 使用 numpy 数组和共享内存并行化 python 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13068760/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com