最近我想使用并行处理加速我的一些代码,因为我有一个四核i7,这似乎是浪费。我学习了python(我使用v 3.3.2,如果它匹配)GIL以及如何使用多处理模块克服它,所以我写了这个简单的测试程序:
from multiprocessing import Process, Queue
def sum(a,b):
su=0
for i in range(a,b):
su+=i
q.put(su)
q= Queue()
p1=Process(target=sum, args=(1,25*10**7))
p2=Process(target=sum, args=(25*10**7,5*10**8))
p3=Process(target=sum, args=(5*10**8,75*10**7))
p4=Process(target=sum, args=(75*10**7,10**9))
p1.run()
p2.run()
p3.run()
p4.run()
r1=q.get()
r2=q.get()
r3=q.get()
r4=q.get()
print(r1+r2+r3+r4)
使用cProfile测量代码运行大约48秒,但是单个进程代码
def sum(a,b):
su=0
for i in range(a,b):
su+=i
print(su)
sum(1,10**9)
在大约50秒内运行。我知道这种方法有开销,但我预计改进会更加激烈。使用fork()的error不适用于我,因为我在Mac上运行代码。
答案 0 :(得分:6)
问题在于您是在呼叫run
而不是start
。
如果您阅读了文档,run
是“表示流程活动的方法”,而start
是启动流程在后台流程上的活动的功能。 (这与threading.Thread
相同。)
所以,你正在做的是在主进程上运行sum
函数,从不对后台进程做任何事情。
从笔记本电脑的定时测试开始,这将时间缩短到原来的37%左右。不是你希望的25%,我不确定为什么,但......足以证明它真的是多处理。 (那个,以及我得到四个额外的Python
进程,每个进程使用60-100%的CPU ......)
答案 1 :(得分:2)
如果你真的想用python编写快速计算,那就不行了。使用numpy或cython。你的计算速度将比普通python快100倍。
另一方面,如果您只想推出一系列parralel作业,请使用适当的工具,例如
from multiprocessing import Pool
def mysum(a,b):
su=0
for i in range(a,b):
su+=i
return su
with Pool() as pool:
print(sum(pool.starmap(mysum, ((1,25*10**7),
(25*10**7,5*10**8),
(5*10**7,75*10**7),
(75*10**7,10**9)))))