我试图测量一段代码,我使用Python的多处理程序包“并行化”,特别是使用Process函数。引入多处理队列时执行时间增加
我有,我想并行运行两个功能:function1
和function2
。 function1
不返回值,function2
。函数2的返回值是一个相当大的类实例。
这里是我现有的使用队列并行并获得返回值码:
import multiprocessing as mpc
...
def Wrapper(self,...):
jobs = []
q = mpc.Queue()
p1 = mpc.Process(target=self.function1,args=(timestep,))
jobs.append(p1)
p2 = mpc.Process(target=self.function2,args=(timestep,arg1,arg2,arg3,...,q))
jobs.append(p2)
for j in jobs:
j.start()
result = q.get()
for j in jobs:
j.join()
所以,这里是我看到的问题。如果我删除了对result = q.get()
的调用,执行Wrapper函数所需的时间显着减少,因为它不是从function2
返回类,但是我显然没有从函数中获取我需要的数据。如果我把它放回来,运行时间会大大增加,从而表明并行化实际上比顺序执行这两个函数花费的时间更长。
下面是一些意味着包装的执行时间,以供参考:
顺序码(即,
function1(timestep)
,res = function2(timestep,a1,a2,a3,...,None)
):10秒并行化的代码,而无需使用一个队列:8秒
带队列的并行码:60秒
此代码的目标是展示如何并行化一段代码可以提高执行不必要的并行函数所需的时间。作为参考,我使用cProfile包,生成我的代码配置文件,并查看Wrapper运行所需的时间。
我开始对整个过程感到沮丧。它的目的是基本上加速我已经添加到内部开发的现有自定义框架中的部分程序,但是我无法实际表明我没有增加太多开销。
如果我看节目的总执行时间,并行化的代码运行得更快。但是,当我深入挖掘时,我的并行代码开始显得需要更长的时间。
现在,我的想法是,队列正在做某种深层复制操作,但是我找不到引用来说明这一事实,所以我假设它正在返回一个浅拷贝,对我而言,不应该要求这样的开销。
虽然有些令人沮丧听到(因为这是我害怕的东西),这是一个很好的答案。正如我试图展示一个比较,你认为为并行和非并行代码创建Manager服务器是值得的吗?我认为如果两者都使用相同类型的共享对象,那么在计算我的应用程序时,性能下降可能不太明显。 – espais 2015-02-18 14:56:34
@espais,好吧,如果你只是为了演示的目的而这样做,那么你可以为并行和顺序代码使用'Manager'。但是如果你想对“这里是如何平行化代码影响其性能”做一个准确的比较,现实情况是顺序代码不需要'Manager',而并行代码则需要。如果你只是试图展示并行化的力量,而这段代码是一个随心所欲的选择,理想情况下你会有一个需要较少共享状态的例子,所以并行化实际上更快......(续) ) – dano 2015-02-18 16:48:48
@espais因为现在你实际上发现,由于Python的限制,并行化这些特定的代码实际上会伤害性能。理想情况下,你会发现你的代码库真的会从并行获益,但你可能没有任何合适的东西。 – dano 2015-02-18 16:50:02