赛通
Cython具有OpenMP支持:使用 Cython,可以通过使用prange
(并行范围)运算符并将-fopenmp
编译器指令添加到 setup.py 来添加 OpenMP。
在 prange 节中工作时,执行是并行执行的,因为我们通过使用指定禁用 GIL 的块来禁用全局解释器锁 (GIL) 。with nogil:
要编译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,
,我们可以选择不同的调度方法。使用静态,工作负载均匀分布在可用的 CPU 上。但是,由于您的一些计算区域在时间上很昂贵,而另一些则很便宜 - 如果我们要求 Cython 在 CPU 上使用静态平均调度工作块,那么某些区域的结果将比其他区域更快地完成,然后这些线程将闲着。动态的和引导的调度选项试图通过在运行时动态地分配更小的块来缓解这个问题,以便在工作负载的计算时间可变时 CPU 分布更均匀。因此,对于您的代码,正确的选择将取决于您的工作负载的性质。
努巴
Numba 的高级版本 NumbaPro 具有对prange
并行化运算符的实验性支持,可与 OpenMP 一起使用。
吡斯兰
Pythran(Python 子集的 Python 到 C++ 编译器)可以利用矢量化可能性和基于 OpenMP 的并行化可能性,尽管它仅使用 Python 2.7 运行。您可以使用指令指定并行部分pragma omp
(非常类似于上述 Cython 的 OpenMP 支持),例如:
派皮
JIT Python 编译器 PyPy 支持多处理模块(见下文),并有一个名为 PyPy-STM 的项目“PyPy的特殊开发版本,它可以在同一进程中并行运行多个独立的 CPU 密集型线程”。
旁注:多处理
OpenMP 是多核的低级接口。您可能想查看multiprocessing.
该multiprocessing
模块在更高级别上工作,共享 Python 数据结构,而 OpenMP 在您编译为 C 后与 C 原始对象(例如整数和浮点数)一起工作。只有在您使用 OpenMP 时才有意义'正在编译你的代码;如果您不进行编译(例如,如果您使用高效的numpy代码并且希望在多个内核上运行),那么坚持使用multiprocessing
可能是正确的方法。