7

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

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

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

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


编辑.

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

4

3 回答 3

3

我会查看multiprocessing (doc),它提供了一堆用于生成和处理子流程的好工具。

引用文档:

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

从评论中我认为Poolmap将符合您的目的(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
于 2012-11-29T00:52:14.587 回答
1

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

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

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

这可以与单个共享队列一起使用,但您需要一个在等待时不会阻塞工作池的队列,而且我不认为multiprocessingPool可以Queue开箱即用地做到这一点。一旦你的所有进程都在等待加入他们的子进程,就什么也做不了。

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

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

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

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

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

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

于 2012-11-29T21:41:47.990 回答
-1

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

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

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

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

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

于 2012-11-29T01:23:19.630 回答