首页 > 解决方案 > 用于小型计算的 Python 可扩展并行处理

问题描述

我正在从事一个项目,该项目本质上是数值积分(Runge-Kutta),用于矢量场中可能存在数百个粒子的路径。我已经探索过使用 Dask 来并行化任务,但我不确定我的问题是否与 Dask 的专长相符。Dask 通过利用并行处理(每次计算可能需要一分钟)来处理大于内存的数据。我的问题是大约 100,000 次 1 秒计算。

只是为了显示其中一项计算是什么:

def RK4(field, x0, y0, t0, dt):
    k1x, k1y = field.interpolate(x0, y0, t0) #predefined interpolation routine using scipy.interpolate
    xi = x0+.5*k1x*dt
    yi = y0+.5*k1x*dt
    k2x, k2y = field.interpolate(xi, yi, t0+.5*dt)
    xi = x0+.5*k2x*dt
    yi = y0+.5*k2x*dt
    k3x, k3y = field.interpolate(xi, yi, t0+.5*dt)
    xi = x0+k3x*dt
    yi = y0+k3x*dt
    k4x, k4y = field.interpolate(xi, yi, t0+dt)

    xi = x0+1/6*(k1x*dt+2*k2x*dt+2*k3x*dt+k4x*dt)
    yi = y0+1/6*(k1y*dt+2*k2y*dt+2*k3y*dt+k4y*dt)

    return xi, yi, t0+dt

以上将在每个 100 个粒子上运行大约 100 次。在 HPC/云上进行扩展的能力至关重要。理想的情况是一次做一批粒子,但由于 scipy.interpolate 依赖,我有一个 GIL 问题。

感谢您的任何建议!

标签: pythondata-sciencedaskdask-distributed

解决方案


Dask 通常用于磁盘或分布式数据处理,它不是在这种特殊情况下使用的最佳工具。

相反,考虑使用 Cython/Numba/Pypy 来实现数字运算,就像你的例子一样。这将通过将函数预编译到二进制库中来绕过 GIL,然后 CPython 可以在本地使用这些库。这会导致 5-10 倍的加速,具体取决于手头的任务。

此外,如果您的粒子可以并行处理,您应该考虑 multiprocessing/ray 以进一步利用多个 cpu 内核。

如果您执行了这两个步骤并且仍然在性能方面遇到困难,请检查算法渐近并寻找替代算法。


推荐阅读