我在Windows HPC群集上运行Python脚本。脚本中的函数使用starmap
包中的multiprocessing
来并行化某个计算密集型进程。
当我在单个非群集机器上运行脚本时,我获得了预期的速度提升。当我登录节点并在本地运行脚本时,我获得了预期的速度提升。但是,当作业管理器运行脚本时,multiprocessing
的速度提升可以完全缓解,有时甚至会慢2倍。我们注意到,在调用starmap
函数时会发生内存分页。我们认为这与Python的multiprocessing
的本质有关,即每个核心都会启动一个单独的Python解释器。
由于我们从单个节点从控制台运行成功,因此我们尝试使用HPC_CREATECONSOLE=True
运行脚本,但无济于事。
在运行使用multiprocessing
的Python脚本时,我们应该使用作业管理器中的某种设置吗? multiprocessing
是否不适合HPC群集?
答案 0 :(得分:3)
不幸的是我无法在社区找到答案。但是,通过实验,我能够更好地隔离问题并找到可行的解决方案。
问题源于Python multiprocessing
实现的本质。创建Pool
对象(即控制并行工作的处理核心的管理器类)时,将为每个核心启动新的Python运行时。我的代码中有多个位置使用multiprocessing
包并实例化Pool
对象...需要它的每个函数根据需要创建一个Pool
对象,然后在之前加入和终止退出。因此,如果我在代码中调用该函数3次,则会旋转8个Python实例,然后关闭3次。在一台机器上,与功能的计算负荷相比,这一点的开销并不显着......但是在高性能计算中,这是非常高的。
我重新设计了代码,以便在调用进程的最开始创建一个Pool
对象,然后根据需要传递给每个函数。它在整个过程结束时关闭,加入和终止。
我们发现大部分时间花在了每个节点上创建Pool
对象上。这是一个改进,因为它只创建了一次!然后我们意识到底层问题是多个节点试图在同一个地方同时从网络上访问Python(它只安装在头节点上)。我们在所有节点上安装了Python和应用程序,问题完全解决了。
这个解决方案是反复试验的结果......遗憾的是,我们对集群计算的了解非常少。我赞同这个答案,希望它会被批评,以便我们能够获得更多的洞察力。谢谢你的时间。