Python 小型计算的可扩展并行处理

Python scalable parallel processing for small calculations

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

只是为了说明其中一项计算是什么:

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/cloud 上扩展的能力是必不可少的。理想情况是一次处理一批粒子,但由于 scipy.interpolate 依赖性,我遇到了 GIL 问题。

感谢任何建议!

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

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

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

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