Python 当使用map()时,multiprocessing.Pool中的进程表现出非常不同的性能

Python 当使用map()时,multiprocessing.Pool中的进程表现出非常不同的性能,python,scipy,multiprocessing,Python,Scipy,Multiprocessing,我想求解一个微分方程N次,每次用 一组不同的参数多处理因此听起来像 正确的作业工具:让我们定义一个执行以下操作的solve函数 计算解决方案的实际工作并使用 multiprocessing.Pool与map一起在多个 过程 此处代码包含N=8和2个进程: 来自多处理导入池的 导入时间 将numpy作为np导入 从bench import init_模型中,获得_初始解 model=init_model() sol_init=get_initial_solution(模型,np.linspace(

我想求解一个微分方程
N
次,每次用 一组不同的参数<代码>多处理因此听起来像 正确的作业工具:让我们定义一个执行以下操作的
solve
函数 计算解决方案的实际工作并使用
multiprocessing.Pool
map
一起在多个 过程

此处代码包含
N=8
和2个进程:

来自多处理导入池的

导入时间
将numpy作为np导入
从bench import init_模型中,获得_初始解
model=init_model()
sol_init=get_initial_solution(模型,np.linspace(0,1,2),{“Current”:0.67})
Nsteps=10
步骤解算器=model.default解算器
def解算(ind):
st=时间。时间()
步骤\u解决方案=sol\u init
对于步进范围(0,Nsteps):
步骤解=步骤解算器。步骤(
步骤(u)解决方案,,
模型
dt=1,
npts=2,
输入={“当前”:2.0},
save=False
)
返回f“任务{ind}花费了{time.time()-st:.2f}s”
如果名称=“\uuuuu main\uuuuuuuu”:
池(进程=2)为p:
时间=p.map(求解,np.arange(1,9))
打印(“\n”.join(次))
出于调试目的,
solve
不返回解决方案,但 而是进程在函数中花费的时间

执行上述操作(我的计算机有4个内核),我得到:

任务1耗时4.41秒
任务2花了5.59秒
任务3耗时1.67秒
任务4花费了0.62秒
任务5花费了0.61秒
任务6花费了0.72秒
任务7耗时0.68秒
任务8耗时0.53秒
正如您所看到的,在函数
solve
中花费的时间变化很大 跨进程池,跨大范围的值。 请注意,这些结果不是确定性的。i、 如果我执行 同样,上面的脚本将使用一组非常不同的时间 观察。然而,这种随机性是没有理由的 在流程和执行中,要完成的工作的数量是相同的

让我们分析一下进程的执行情况,以获得更多信息 关于那里发生了什么的信息

导入cProfile
输入pstats
def配置文件(ind):
runctx(“solve(ind)”,globals(),locals(),“report_”+str(ind)+“.txt”)
池(进程=2)为p:
时间=p.map(剖面图,np.arange(1,9))
对于范围(1,9)内的ind:
stats=pstats.stats(“报告”+str(ind)+“.txt”).strip_dirs()
统计数据。排序_统计数据(“累计”)
统计数据。打印统计数据(11)
例如,如果我们查看任务1和7的报告:

周四10月29日18:07:18 2020年报告\u 1.txt
0.895秒内完成75858次函数调用(75426次基本调用)
排序人:累计时间
由于限制,名单从249份减少到11份
ncalls tottime percall cumtime percall文件名:lineno(函数)
1 0.000 0.000 0.895 0.895{内置方法builtins.exec}
1    0.000    0.000    0.895    0.895 :1()
1 0.000 0.000 0.895 0.895 python-1mtcbY:15(求解)
10 0.001 0.000 0.895 0.090基础解算器py:712(步骤)
10 0.001 0.000 0.892 0.089 scipy_解算器。py:35(_积分)
10 0.003 0.000 0.889 0.089 ivp.py:156(求解ivp)
88 0.001 0.000 0.738 0.008基准。py:159(步骤)
88 0.010 0.000 0.738 0.008 bdf.py:296(步骤实施)
45 0.000 0.000 0.668 0.015 bdf.py:216(lu)
45 0.666 0.015 0.668 0.015反编译lu.py:15(lu系数)
1284 0.003 0.000 0.139 0.000基本解算器。py:906(uuuu调用)
周四10月29日18:07:27 2020年报告_7.txt
在6.773秒内完成75831个函数调用(75399个基元调用)
排序人:累计时间
由于限制,名单从244人减至11人
ncalls tottime percall cumtime percall文件名:lineno(函数)
1 0.000 0.000 6.773 6.773{内置方法builtins.exec}
1    0.000    0.000    6.773    6.773 :1()
1 0.000 0.000 6.773 6.773 python-1mtcbY:15(求解)
10 0.001 0.000 6.773 0.677基本解算器py:712(步骤)
10 0.000 0.000 6.770 0.677 scipy_解算器。py:35(_积分)
10 0.002 0.000 6.769 0.677 ivp.py:156(求解ivp)
88 0.001 0.000 6.612 0.075基准。py:159(步骤)
88 0.011 0.000 6.612 0.075 bdf.py:296(步骤实施)
45 0.000 0.000 6.520 0.145巴西第纳尔比:216(卢布)
45 6.519 0.145 6.520 0.145反编译lu.py:15(lu系数)
1284 0.003 0.000 0.146 0.000基本求解器。py:906
上述情况告诉我们,在这两种情况下(所有人都是如此) 任务),该流程的大部分生命周期都在Scipy中度过
lu\u系数
。然而,令人惊讶的是(至少让我感到惊讶的是) 花费在
lu_因子
上的时间因任务而异。这是

我想理解的是。

这大概是由于全局可变状态;前两个任务是“慢”任务,对应于池中的进程数

我建议通过移动使事情更加确定

model=init_model()
sol_init=get_initial_solution(模型,np.linspace(0,1,2),{“Current”:0.67})

内部
求解

可能这是由于全局可变状态;前两个任务是“慢”任务,对应于池中的进程数

我建议通过移动使事情更加确定

model=init_model()
sol_init=get_initial_solution(模型,np.linspace(0,1,2),{“Current”:0.67})

内部
solve

lu\u factor
是LAPACK的
getrf
例程的包装器,它本身依赖于BLAS。在我的例子中,底层BLAS实现是OpenBlas,在使用
pip从PyPI安装scipy时,在scipy控制盘内部提供Task 1 took 0.19s
Task 2 took 0.19s
Task 3 took 0.18s
Task 4 took 0.18s
Task 5 took 0.18s
Task 6 took 0.18s
Task 7 took 0.18s
Task 8 took 0.18s