Cython
Cython支持OpenMP:使用Cython,可以通过使用prange
(并行范围)运算符并将-fopenmp
编译器指令添加到setup.py中来添加OpenMP。
在prange土台中工作时,由于使用with nogil:
来指定禁用GIL的块,因此执行是并行执行的。
要编译cython_np.pyx,我们必须修改setup.py脚本,如下所示。 我们命令它在编译过程中通知C编译器使用-fopenmp
作为参数-启用OpenMP并链接OpenMP库。
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(
cmdclass = {"build_ext": build_ext},
ext_modules = [
Extension(
"calculate",
["cython_np.pyx"],
extra_compile_args = ["-fopenmp"],
extra_link_args = ["-fopenmp"]
)
]
)
通过Cython的prange,
我们可以选择不同的调度方式。使用静态(static),工作负载会均匀地分布在可用的CPU上。然而,由于某些计算区域的时间成本很高,而其他区域的成本较低 - 如果我们要求Cython在CPU上使用静态(static)平均分配工作块,那么一些区域的结果将比其他区域更快完成,而这些线程将闲置。
动态(dynamic)和导向(guided)调度选项都尝试通过在运行时动态分配较小的工作块来缓解此问题,以使CPU在工作负载的计算时间变化较大时更均匀地分布。因此,在您的代码中,正确的选择取决于工作负载的性质。
Numba
Numba的高级版本NumbaPro支持使用OpenMP操作符prange
进行并行化的实验性支持。
Pythran
Pythran(用于Python的C ++编译器的子集)可以利用矢量化和基于OpenMP的并行化可能性,但仅在Python 2.7中运行。您可以使用pragma omp
指令指定并行部分(与上面描述的Cython的OpenMP支持非常相似),例如:
![pragma omp](https://istack.dev59.com/iur5X.webp)
PyPy
JIT Python编译器PyPy支持多进程模块(请参见以下内容)并且具有一个名为PyPy-STM的项目,这是“在同一进程中并行运行多个独立的CPU密集线程的特殊开发版本的PyPy”。
附注:multiprocessing
OpenMP是多核接口。您可能需要查看multiprocessing。
该multiprocessing
模块在更高级别上工作,共享Python数据结构,而OpenMP在编译为C后使用C原始对象(例如,整数和浮点数)。如果您正在编译代码,则使用OpenMP才有意义;如果您没有编译代码(例如,如果您正在使用高效的numpy代码并希望在多个核心上运行),则坚持使用multiprocessing
可能是正确的方法。
prange
现在似乎已经在 Numba 中普遍可用了。您可以在 https://numba.readthedocs.io/en/stable/user/parallel.html 上找到更多相关信息。 - shadowtalker