【问题标题】:parallel python, or MPI?并行python,还是MPI?
【发布时间】:2012-11-17 00:13:25
【问题描述】:

我有一个包含大量符号计算的代码(许多多个符号积分)。我还可以访问一台 8 核 cpu 计算机(具有 18 GB RAM)和一个小型 32 cpu 集群。我更喜欢留在我教授的 8 核 pc 上,而不是在更有限的时间内使用他的集群去另一个教授的实验室,但是,我不确定它是否可以在 SMP 系统上运行,所以我正在寻找一个 Python 中的 em>并行工具,可以在 SMPClusters 上使用,当然更喜欢一个系统上的代码可以轻松轻松地修改以在其他系统上使用。

到目前为止,我发现 Parallel Python (PP) 很有希望满足我的需求,但我最近告诉 MPI 也可以做到这一点(pyMPI 或 MPI4py)。我不能同意这一点,因为网上似乎很少讨论这个问题,只有 here 声明 MPI(pyMPI 或 MPI4py)仅可用于 集群,如果我是对的关于那个“唯一”!

“Parallel Python”是我唯一的选择,还是我也可以愉快地使用基于 MPI 的解决方案?哪一个更有希望满足我的需求?

附言。似乎他们都没有非常全面的文档,所以如果您知道他们的官方网站以外的一些链接可以帮助新手进行并行计算,如果您在回答中也提到它们,我将不胜感激:)


编辑

我的代码有两个循环,一个在另一个,外循环不能并行化,因为它是一种迭代方法(递归解决方案),每个步骤取决于值在其上一步中计算。外循环包含内循环以及3个额外方程,它们的计算取决于内循环的整个结果。然而,内循环(包含每一步可计算的 12 个方程中的 9 个)可以安全地并行化,所有 3*3 方程彼此独立,仅取决于上一步。我所有的方程计算量都很大,因为每个方程都包含许多多重符号积分。似乎我可以分别并行化 内循环的 9 个方程这 9 个方程中的每个方程 中的积分计算,并且还可以并行化其他 3 个方程中的所有 积分内循环。你可以找到我的代码here,如果它可以帮助你更好地理解我的需求,它写在 SageMath 里面。

【问题讨论】:

  • 我不知道这是否相关,因为它只是您整体解决方案的配套选项,但我想我会添加评论...ZeroMQ 是一种开发方式无论您的“工人”在可扩展性方面是透明的。您可以从本地进程开始,然后简单地将其扩展到通过套接字连接的工作人员。代码逻辑保持不变。
  • MPI 可以在单台计算机上使用,非常容易。但是,除非您正在执行多语言程序或有一些独立的理由来学习 MPI,否则它可能不是您想要的解决方案,因为与多处理相比,要学习的概念更多。
  • zmq 将是系统组件之间的协调和通信形式。假设您决定使用multiprocessing 模块。您可以让 8 个工作进程进入一个接受作业的工作循环,通过 zmq 推/拉进行通信。他们只是消耗工作并将结果传回另一个 zmq 套接字。如果您想将其扩展到 100 台网络机器,它们只需连接同一推/拉以接受工作。系统看不出区别。 python 多进程模块真的是你所需要的。您甚至可以让使用其他语言的工作人员进行连接。
  • 这里的信息太多,无法在两个线程的 cmets 中回复,所以我将它们添加为答案,即使它不是真正的答案。我应该提一下,我很少使用 IPython 的并行功能,所以我无法将其与 multiprocessing 进行比较。
  • @Owari:因为 sage,在 ipython 中运行你的代码很有挑战性!但是您的代码可以很容易地转换为 scipy/numpy/matplotlib 等价物;如果可以的话;那么剩下的部分就很容易了.. .

标签: python parallel-processing cluster-computing mpi smp


【解决方案1】:

我会关注multiprocessing (doc),它提供了许多用于生成和处理子进程的好工具。

引用文档:

multiprocessing 是一个支持使用 API 类似于 threading 模块。多处理包 提供本地和远程并发,有效地回避 使用子进程而不是线程来全局解释器锁。

从 cmets 我认为 Pool 和它的 map 将满足您的目的 (doc)

def work_done_in_inner_loop(arg):
    # put your work code here
    pass

p = Pool(9)
for o in outer_loop:
     # what ever else you do
     list_of_args = [...] # what your inner loop currently loops over
     res = p.map(work_done_in_inner_loop,list_of_args])
     # rest of code

【讨论】:

  • 据我了解,多处理可在 SMP 和云上使用,所以我在想如果它可以在云上使用它也应该在本地集群上也可以使用,但没有找到任何东西关于它。你的意思是它也可以在集群上使用?比PP更容易处理吗?感谢您的回答!
  • multiprocessing 可以在一组独立的计算机上运行,​​每台计算机都运行一个“远程管理器”。不管它们是在云中还是在本地集群中,只要您可以在它们之间连接套接字即可。这让事情变得非常简单——但这确实意味着如果您的集群中有任何花哨的功能,multiprocessing 将不会利用它们。
  • @abarnert,所以多处理不是集群计算的一般好选择,对吧?比PP好吗?我的意思是更简单或更实用。另外,远程管理器是什么意思?它是像filezilla这样的独立应用程序吗?抱歉这个菜鸟问题。
  • 远程管理器只是一个 Python 实例,没什么复杂的。如果您的集群基本上是具有快速本地网络的网格,multiprocessing 是集群计算的不错选择;如果您想利用主/从负载平衡、硬件 PVM 加速、集群文件系统的特殊功能等,那就不太好。
  • @owari 您应该将最后两个 cmets 移到您的问题中。
【解决方案2】:

似乎有一些合理的设计方法。

让我将您的工作称为主要工作、9 个中间工作以及中间工作可以衍生的许多内部工作。我假设中间作业在内部作业全部完成后有一个“合并”步骤,外部作业也是如此。

最简单的设计是主作业触发中间作业,然后在执行合并步骤之前等待它们全部完成。然后中间作业触发内部作业并等待它们全部完成,然后再执行合并步骤。

这可以与单个共享队列一起使用,但您需要一个在等待时不会阻塞工作池的队列,我认为 multiprocessingPoolQueue 无法做到这一点的盒子。一旦你的所有进程都等待加入他们的子进程,什么都做不了。

解决此问题的一种方法是更改​​为延续传递样式。如果您知道哪个中间作业将最后完成,您可以将句柄传递给其他中间作业并让它加入它们并执行合并,而不是外部作业。中间人同样将合并传递给他们最后的内部工作。

问题在于,即使没有日程安排问题,您通常也无法知道最后会完成什么。因此,这意味着您需要某种形式的共享(例如,信号量)或作业之间的消息传递来在它们之间进行协商。您可以在multiprocessing 之上执行此操作。唯一的问题是它破坏了您工作的独立性,并且您突然要处理所有令人讨厌的共享并发问题。

另一种选择是为每个中间作业设置单独的池和队列,并在池之间进行某种负载平衡,以确保每个核心都运行一个活动进程。

或者,当然,一个比 multiprocessing 实现更复杂的单个池,它可以进行负载平衡或协作调度,因此加入者不会阻塞核心。

或者一个超级简单的解决方案:过度调度,并为简单起见在上下文切换中付出一点代价。例如,即使您只有 8 个内核,您也可以运行 32 个工作程序,因此您有 22 个活动工作程序和 10 个等待工作程序。每个核心有 2 或 3 个活跃的工作人员,这会减慢一些速度,但可能不会太糟糕 - 至少没有人闲置,除了将不同的参数传递给 multiprocessing.Pool 构造函数之外,您无需编写任何代码.

无论如何,multiprocessing 非常简单,几乎没有多余的概念不适用于其他解决方案。因此,在遇到砖墙或不撞墙之前,可能会花费更少的时间,而不是提前尝试弄清楚它是否适合您。

【讨论】:

  • 谢谢,你的回答对我很有帮助和启发:) 你最后的两个建议似乎更直观,因此对我来说更容易理解。
【解决方案3】:

我最近遇到了类似的问题。但是,以下解决方案仅在以下情况下有效:(1) 您希望在一组文件上单独运行 python 脚本,并且 (2) 脚本的每次调用都独立于其他脚本。

如果上述情况适用于您,最简单的解决方案是在 bash 中编写一个包装器,如下所示:

for a_file in $list_of_files
do
    python python_script.py a_file &
done

'&' 将作为子进程运行前面的命令。优点是 bash 在继续 for 循环之前不会等待 python 脚本完成。

您可能希望限制同时运行的进程数,因为此代码将使用所有可用资源。

【讨论】:

  • 这似乎不太适合 OP 的要求。它只是一堆从外部输入参数运行的完全独立的进程。多处理的想法是能够处理一个问题并将其拆分,然后将结果合并回来。这只是一个原始的 bash 包装器,用于处理对文件列表的“void”返回操作。
  • @immattbatt,感谢您的解决方案,我也许可以将需要单独计算的每个集成放在一个文件中,但这将非常困难且耗时。此外,我不确定这个答案将如何并行化我的代码,因为不同的集成有时会使用相似的数据,例如在上一步中找到的同一函数的不同函数。但是,感谢您的时间和精力:)
猜你喜欢
  • 2011-08-13
  • 1970-01-01
  • 2012-11-13
  • 1970-01-01
  • 2017-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-10
相关资源
最近更新 更多