赛通
Cython 具有 OpenMP 支持:使用 Cython,可以通过使用 prange(并行范围)运算符并添加 -fopenmp 编译器指令来设置 OpenMP .py.
在 prange 节中工作时,执行是并行执行的,因为我们通过使用 with nogil: 指定禁用 GIL 的块来禁用 全局解释器锁 (GIL)。 p>
要编译 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 的高级版本 NumbaPro 具有对 prange 并行化运算符的实验性支持,可与 OpenMP 一起使用。
Pythran
Pythran(Python 子集的 Python 到 C++ 编译器)可以利用矢量化可能性和基于 OpenMP 的并行化可能性,尽管它仅使用 Python 2.7 运行。您可以使用 pragma omp 指令指定并行部分(非常类似于上述 Cython 的 OpenMP 支持),例如:
PyPy
>
JIT Python 编译器 PyPy 支持多处理模块(见下文),并有一个名为 PyPy-STM "a special in-development version of PyPy which can run multiple independent CPU-hungry threads in the same process in parallel" 的项目。
旁注:多处理
OpenMP 是多核的低级接口。您可能想查看multiprocessing. multiprocessing 模块在更高级别上工作,共享 Python 数据结构,而 OpenMP 在您编译为 C 后与 C 原始对象(例如,整数和浮点数)一起工作。它只会使如果你正在编译你的代码,那么使用 OpenMP 是有意义的;如果您不进行编译(例如,如果您使用高效的 numpy 代码并且希望在多个内核上运行),那么坚持使用 multiprocessing 可能是正确的方法。