并行调用 scipy RectBivariateSpline

Parallelization of calls to scipy RectBivariateSpline

我正在编写一个 python 代码,我需要在其中多次评估任意一组点处的 2D 样条曲线。代码如下所示:

spline = scipy.interpolate.RectBivariateSpline(...)
for i in range(1000000):
    x_points, y_points = data.get_output_points(i)
    vals = spline.ev(x_points, y_points)
    """ do stuff with vals """

输出点没有重叠。我想使用线程或某种共享内存来并行化它,因为 data.get_output_points 使用大量内存。天真地,我尝试生成 10 个线程并给它们每个 1/10 的循环。但是,这并没有给我任何比 运行 单个线程更快的速度。

我分析了代码,它的所有时间都花在 fitpack2.py:674(\__call__) 上,这是 _BivariateSplineBase 评估函数。似乎我 运行 遇到了一些 GIL 问题,它阻止了线程独立地 运行。

如何绕过 GIL 问题并将其并行化?有没有办法调用可以很好并行化的 fitpack 例程,或者我可以使用不同的样条曲线?我的输入网格是统一的和过采样的,但我的输出点可以在任何地方。我已经尝试使用 RegularGridInterpolator(线性插值),它具有足够好的性能,虽然不理想,但它使用线程并行化很差。

编辑:这就是我所说的简单线程并行化的意思:

def worker(start, end):
    for i in range(start, end):
        x_points, y_points = data.get_output_points(i)
        vals = spline.ev(x_points, y_points)
        """ do stuff with vals """

t1 = threading.Thread(target=worker, args=(0, 500000)).start()
t2 = threading.Thread(target=worker, args=(500001, 1000000)).start()
t1.join()
t2.join()

在python中有多种方法可以并行处理以避免GIL:

有关更多信息,请参阅 here

是的,您 碰到了 GIL 颈瓶。