【问题标题】:Parallelization of calls to scipy RectBivariateSplinescipy RectBivariateSpline 调用的并行化
【发布时间】:2015-10-19 17:44:31
【问题描述】:

我正在编写一个 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()

【问题讨论】:

  • 您能告诉我们如何您并行化该代码吗?
  • 当然,我添加了一个示例。我只是在不同线程之间拆分 for 循环。

标签: python multithreading numpy parallel-processing scipy


【解决方案1】:

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

更多信息请见here

是的,你正在击中 GIL 的瓶颈。

【讨论】:

  • 是的,你是对的。我对此进行了更多研究,并且 dfitpack 代码从不禁用 GIL,因此无法执行我希望对线程执行的操作。我不确定为什么在进入 fortran 代码时它会保留 GIL,但这可能只是因为没有人花时间弄清楚什么可以禁用 GIL,什么不能。我将重组一切以使用多处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-17
  • 1970-01-01
  • 2012-10-04
  • 2015-10-14
  • 1970-01-01
  • 2017-05-26
  • 2013-05-24
相关资源
最近更新 更多