python - 用于小型计算的 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 问题。
感谢您的任何建议!
解决方案
Dask 通常用于磁盘或分布式数据处理,它不是在这种特殊情况下使用的最佳工具。
相反,考虑使用 Cython/Numba/Pypy 来实现数字运算,就像你的例子一样。这将通过将函数预编译到二进制库中来绕过 GIL,然后 CPython 可以在本地使用这些库。这会导致 5-10 倍的加速,具体取决于手头的任务。
此外,如果您的粒子可以并行处理,您应该考虑 multiprocessing/ray 以进一步利用多个 cpu 内核。
如果您执行了这两个步骤并且仍然在性能方面遇到困难,请检查算法渐近并寻找替代算法。
推荐阅读
- android - 可绘制android中各个方向的渐变边框
- javascript - 如何在 jquery datacolumn 的动态列中设置 SeverSide?
- java - 在 Spring Boot 中将文件上传到 S3 并将它们存储在类路径中
- php - 从目录中读取文本文件
- javascript - 如何过滤和排列并返回具有索引值的新对象数组?
- c# - 是否可以仅使用 LINQ 将 2 个数组合并为具有 2 个字段的结构数组?
- git - 我可以防止在一周中的某些时间合并拉取请求吗?
- ios - iOS UiTableViewCell 子视图中的手势识别器
- css - 无法使用材质 UI 样式更改图标颜色
- file - 有没有办法从 Hadoop hdfs 中列出文件并将文件名存储到本地而不是实际文件本身?