我正在使用multiprocessing
Python 中的模块,并期望启动进程、创建队列以及向队列中放入值或从队列中获取值会产生一些开销。但是,如果子流程有足够的工作要做,我预计开销最终会被消除。运行一个简单的示例(如下所述),我生成的进程的运行时间大约是从父进程启动的同一进程的 10 倍,即使对于非常大的作业也是如此。
在下面的代码中,我计算一系列越来越大的数组的平均值。我比较打电话numpy.mean
从父进程到从单个生成的进程调用相同的均值函数,以及在生成的进程中不执行任何操作(以了解开销成本)。
最初,结果正如我所预期的那样。总运行时间要快得多mean
从父进程调用而不是从派生进程调用。对于小型作业,生成进程的运行时间主要由开销决定。
然而,令人惊讶的是,对于较大的作业,生成的进程的运行时间始终超过从父进程调用的成本约 10 倍。
谁能对此提供解释?这是由于子进程的内存限制吗?我测试的最大阵列有 125MB、500MB 和 2GB。
这是代码:
%matplotlib
import numpy, multiprocessing, pandas
def do_nothing(x,q):
q.put(x[-1])
def my_mean(x,q):
q.put(numpy.mean(x))
def test_mp(f,x):
q = multiprocessing.Queue()
p = multiprocessing.Process(target=f,args=(x,q))
p.start()
p.join()
s = q.get()
return s
ndata = 2**numpy.arange(10,29,2)
tr1,tr2,tr3 = [[],[],[]]
for n in ndata:
x = numpy.random.rand(n)
tresults = %timeit -n 1 -r 5 -o -q test_mp(do_nothing,x)
tr1.append(tresults)
tresults = %timeit -n 1 -r 5 -o -q test_mp(my_mean,x)
tr2.append(tresults)
tresults = %timeit -n 1 -r 5 -o -q numpy.mean(x)
tr3.append(tresults)
print("All done")
t1,t2,t3 = map(lambda tr : pandas.Series([1000*t.best for t in tr]),[tr1,tr2,tr3])
df = pandas.DataFrame({'n' : ndata, 't1 (do nothing)' : t1,
't2 (my_mean)' : t2,
't3 (mean)' : t3})
display(df)
df.plot(x='n',style='.-',markersize=10,logx=True,logy=True)
这是结果。所有计时结果均以毫秒为单位。