【问题标题】:Using Python multiprocessing on an HPC cluster在 HPC 集群上使用 Python 多处理
【发布时间】:2016-09-10 07:23:06
【问题描述】:

我正在 Windows HPC 集群上运行 Python 脚本。脚本中的一个函数使用multiprocessing 包中的starmap 来并行化某个计算密集型进程。

当我在单个非集群机器上运行脚本时,我获得了预期的速度提升。当我登录到一个节点并在本地运行脚本时,我获得了预期的速度提升。但是,当作业管理器运行脚本时,multiprocessing 的速度提升要么完全减轻,有时甚至慢 2 倍。我们注意到在调用starmap 函数时会发生内存分页。我们认为这与 Python 的 multiprocessing 的性质有关,即为每个内核启动了单独的 Python 解释器这一事实。

由于我们从单个节点的控制台成功运行,我们尝试使用HPC_CREATECONSOLE=True 运行脚本,但无济于事。

在运行使用multiprocessing 的Python 脚本时,我们应该使用作业管理器中的某种设置吗? multiprocessing 是否不适合 HPC 集群?

【问题讨论】:

    标签: python-3.x multiprocessing distributed-computing hpc


    【解决方案1】:

    很遗憾,我无法在社区中找到答案。但是,通过实验,我能够更好地隔离问题并找到可行的解决方案。

    问题源于 Python 的 multiprocessing 实现的性质。当创建Pool 对象(即控制并行工作的处理核心的管理器类)时,将为每个核心启动一个新的 Python 运行时。我的代码中有多个地方使用了multiprocessing 包并实例化了Pool 对象......每个需要它的函数都根据需要创建一个Pool 对象,然后在退出之前加入并终止。因此,如果我在代码中调用该函数 3 次,则会启动 8 个 Python 实例,然后关闭 3 次。在单机上,与函数的计算负载相比,这种开销根本不显着……但在 HPC 上却高得离谱。

    我重新设计了代码,以便在进程调用的最开始创建一个Pool 对象,然后根据需要传递给每个函数。它在整个过程结束时关闭、连接和终止。

    我们发现大部分时间都花在了在每个节点上创建 Pool 对象上。这是一个改进,因为它只被创建一次!然后我们意识到潜在的问题是多个节点试图通过网络同时在同一个地方访问 Python(它只安装在头节点上)。我们在所有节点上安装了 Python 和应用程序,问题完全解决了。

    这个解决方案是反复试验的结果......不幸的是,我们目前对集群计算的了解还很低。我分享这个答案,希望它会受到批评,以便我们能够获得更多的见解。感谢您的宝贵时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多