用于共享内存并行编程的 Python 指南

计算科学 并行计算 Python
2021-12-13 04:02:29

我有为共享内存机器(在 C 和 FORTRAN 中)编写 OpenMP 的经验,以执行简单的任务,如矩阵加法、乘法等(只是想看看它如何与 LAPACK 竞争)。我对 OpenMP 的了解足以执行简单的任务,而无需查看文档。

最近,我为我的项目转向了 Python,除了绝对基础之外,我没有任何 Python 经验。

我有两个问题:

  • 是否有一个很好的指南(在线 PDF)来描述 Python 的共享内存并行计算?

  • 实现它的最佳方法是什么?我已经看到了一点,ctypes我不确定这是否是最好的方法。(最好我的意思是在程序员时间和系统时间之间有一个很好的权衡。编码不应该太乏味,执行也不应该很慢)

2个回答

[这是我的第一篇文章,我希望我没有完全误解 SE 的使用 - 如果是这样,我提前道歉]

我同意“bgschaid”的观点,即根据所提供的信息很难回答这个问题。如果您希望低级例程利用多核架构,或者如果您需要利用并行性来解决令人尴尬的并行问题 - 或介于两者之间的问题,这会产生巨大的差异。可以在此处找到 Python 中不同并行计算可能性的概述。

在前一种情况下,我肯定建议使用NumPy / SciPy等工具,至少在 Enthought 的 MKL 编译版本中,它们支持多核架构。在这里,您可以通过环境变量“MKL_NUM_THREADS”控制要使用的内核数量。这依赖于高度优化的库,我们几乎不能指望在性能方面超越这些库。我相信通常建议尽可能使用这些高质量和高度优化的库。

如果您希望在粗略的水平上利用并行性,Python 标准工具multiprocessing很容易使用 - 它还支持共享数据对象。有不同的工具可用作多处理包的一部分。我已经使用map_async (SIMD like) 和apply_async (MIMD like) 来解决几个问题,效果很好。multiprocessing包非常易于使用,并且作为 Python的标准部分意味着您可以期望您的代码的其他潜在用户能够轻松使用它。 多处理也直接链接到 NumPy 数据对象。使用多处理时我建议您将环境变量“MKL_NUM_THREADS”设置为 1,这样NumPy只允许每个进程/工作人员使用一个内核 - 否则您可能最终会导致 NumPy 并行和多处理之间的资源争用,从而导致性能下降。 多处理适用于同一操作系统下的多 CPU/多核架构。在具有 4 个 Xeon E7-4850 CPU(每个 10 个内核)和 512 GB 内存的共享内存计算机上使用了多处理,它运行得非常好。共享数组可以由multiprocessing.Arraysharedctypes处理。您可以在此处找到 Python 文档- 检查库.pdf文件。我有一些幻灯片解释了其中的一些基本部分——如果你想要这些,请 PM 我。

如果您有分布式内存的集群配置,我相信mpi4py可能是首选工具。我自己没有使用过它,但我知道它在 Python 并行编程中被大量使用。

这取决于您尝试并行编程的级别。例如,对于矩阵/向量的东西,python 的第一站是 NumPy/SciPy(它们为数字库提供了一个接口,让你在 Python 的便利下获得库的全速),从他们写的关于并行性的文章看来,如果库是为并行使用而编译的,那么程序会利用多核来进行某些操作。(好像这篇文章有点老了,操作系统的东西可能在此期间有所改进。还有其他并行编程方式的链接。

当然还有mpi4py可以直接对 MPI 进行编程(包含在上面的文章中)

我的底线是:如果您的主要兴趣是向量/矩阵运算并且并行性是您“只”需要快速完成的事情,那么您应该看看 NumPy/SciPy 生态系统,并且只有在您没有找到如果您考虑编写自己的库,您需要的东西