如何在 Python 中有效地将大块数据扇出到多个并发子进程中?

How to efficiently fan out large chunks of data into multiple concurrent sub-processes in Python?

[我在 Windows 中使用 Python 3.5.2 (x64)。]

我正在读取大块(以兆字节为单位)的二进制数据,并希望有效地将数据共享到 'n' 并发 Python 子进程(每个进程将处理以独特且计算量大的方式处理数据)。

数据是只读的,在所有子进程完成之前,每个顺序块都不会被视为"processed"。

我专注于共享内存(数组(锁定/解锁)和 RawArray):将数据块从文件读入缓冲区非常快,但将该块复制到共享内存的速度明显较慢。

对于队列,相对于共享内存,那里会进行大量冗余数据复制。我选择共享内存是因为它涉及一个副本而不是 'n' 个数据副本)。

在架构上,如何在 Python 3.5 中有效地处理这个问题?

编辑:到目前为止,我已经收集了两件事:Windows 中的内存映射很麻烦,因为涉及酸洗才能实现它,multiprocessing.Queue(更具体地说, JoinableQueue) 虽然不是(还)最优但速度更快。

编辑 2:我收集到的另一件事是,如果您有很多工作要做(特别是在 Windows,其中 spawn() 是唯一的选择,而且成本很高也),创建长 运行 并行进程比一遍又一遍地创建它们要好。

仍然非常欢迎提出建议 - 最好是使用 multiprocessing 组件的建议!

在 Unix 中,这可能很容易处理,因为 fork() 用于多处理,但在 Windows 中,事实上 spawn() 是它工作的唯一方式,这确实限制了选项。然而,这意味着是一个多平台解决方案(我将主要在 Windows 中使用它)所以我在这个限制范围内工作。

我可以在每个子进程中打开数据源,但取决于数据源在带宽方面可能很昂贵,或者如果它是流,则可能会让人望而却步。这就是我采用一次读取方法的原因。

通过 mmap 共享内存和匿名内存分配似乎很理想,但是要将对象传递给子进程需要对其进行 pickle - 但您不能 pickle mmap 对象。就这么多了。

通过 cython 模块共享内存可能是不可能的,也可能不是,但它几乎肯定是令人望而却步的 - 并且回避了使用更合适的语言来完成任务的问题。

通过共享 ArrayRawArray 功能的共享内存在性能方面成本很高。

队列效果最好 - 但内部 I/O 由于我认为在后台进行酸洗是惊人的。但是,少量并行进程的性能下降不太明显(尽管这可能是更快系统的限制因素)。

我可能会用另一种语言重新考虑 a) 体验! b) 看看我是否可以避免 I/O 要求 Python 队列引起的。进程之间的快速内存缓存(我希望在这里实现)将避免大量冗余 I/O.

虽然 Python 应用广泛,但没有任何工具适合所有工作,这只是其中一种情况。在这个过程中,我学到了很多关于 Python 的 multiprocessing 模块的知识!

至此,我似乎已经尽我所能使用标准 CPython,但仍然欢迎提出建议!