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