在下面的代码中,我计算了在使用管道传递过程时使用args
关键字将大型数组(8 MB)传递给子进程所需的时间。
有没有人知道为什么使用参数传递数据比使用管道快得多?
下面,每个代码块都是Jupyter笔记本中的一个单元格。
import multiprocessing as mp
import random
N = 2**20
x = list(map(lambda x : random.random(),range(N)))
在父进程中调用sum
的时间(仅供比较):
%%timeit -n 5 -r 10 -p 8 -o -q
pass
y = sum(x)/N
t_sum = _
从子进程调用sum
的结果,使用args
关键字将列表x
传递给子进程。
def mean(x,q):
q.put(sum(x))
%%timeit -n 5 -r 10 -p 8 -o -q
pass
q = mp.Queue()
p = mp.Process(target=mean,args=(x,q))
p.start()
p.join()
s = q.get()
m = s/N
t_mean = _
使用管道将数据传递给子进程的时间
def mean_pipe(cp,q):
x = cp.recv()
q.put(sum(x))
%%timeit -n 5 -r 10 -p 8 -o -q
pass
q = mp.Queue()
pipe0,pipe1 = mp.Pipe()
p = mp.Process(target=mean_pipe,args=[pipe0,q])
p.start()
pipe1.send(x)
p.join()
s = q.get()
m = s/N
t_mean_pipe = _
(添加以回应评论)使用mp.Array
共享内存功能(非常慢!)
def mean_pipe_shared(xs,q):
q.put(sum(xs))
%%timeit -n 5 -r 10 -p 8 -o -q
xs = mp.Array('d',x)
q = mp.Queue()
p = mp.Process(target=mean_pipe_shared,args=[xs,q])
p.start()
p.join()
s = q.get()
m = s/N
t_mean_shared = _
打印结果(ms)
print("{:>20s} {:12.4f}".format("MB",8*N/1024**2))
print("{:>20s} {:12.4f}".format("mean (main)",1000*t_sum.best))
print("{:>20s} {:12.4f}".format("mean (args)",1000*t_mean.best))
print("{:>20s} {:12.4f}".format("mean (pipe)",1000*t_mean_pipe.best))
print("{:>20s} {:12.4f}".format("mean (shared)",1000*t_mean_shared.best))
MB 8.0000
mean (main) 7.1931
mean (args) 38.5217
mean (pipe) 136.5020
mean (shared) 4195.0568
使用管道比将参数传递给子进程慢3倍。除非我做错了什么,mp.Array
不是首发。
为什么管道比直接传递给子进程要慢得多(使用args
)?怎么了共享内存?