使用SciPy.optimize进行并行计算

6 投票
2 回答
3630 浏览
提问于 2025-04-16 09:24

我正在做一些研究代码,使用 scipy.optimize.leastsq 来优化一个函数。每次迭代大约要调用这个函数18次,所以我想并行调用它,以减少运行时间。这个问题应该不大,因为这些优化几乎是完全独立的,所以需要的同步很少。我最近了解到 multiprocessing.pool.ThreadPool,这个工具可以让我在不需要特别设置共享内存的情况下实现并行(因为我的大部分数据都在NumPy数组里,这样设置共享内存会很麻烦)。于是我稍微修改了一下我的代码,希望它能正常工作,但却出现了一个奇怪的错误:SystemError: null argument to internal routine

以下是我代码的简化版本:

def optfunc(id):
    def errfunc(x):
        return somedata[id] - somefunc(x)

    lock.acquire()
    x0 = numpy.copy(currentx[id])
    lock.release()

    result = scipy.optimize.leastsq(errfunc, x0)

    lock.acquire()
    currentx[id] = result
    lock.release()

ThreadPool(processes=8).map(optfunc, range(idcount))

这应该可以正常工作,除非 scipy.optimize.leastsq 不是线程安全的。所以我尝试在 scipy.optimize.leastsq 周围加一个锁,结果它确实能工作了。但是,处理器的使用率一直保持在100%,所以这对我来说没什么用。

我的问题是,我该怎么办呢?我觉得我的选择有:

  1. 找一个线程安全的LM实现(也许是levmar?)
  2. 尝试使用进程而不是线程(我觉得这可能没什么区别)

任何帮助或建议都非常感谢。

2 个回答

-1

你有多少个CPU或核心?如果你的程序在运行时已经占满了100%的资源,但没有使用多线程,那就没有什么好处可言。如果leastq()这个函数不是线程安全的,而且你没有把电脑的资源用到极限,那么你可以在每个核心上运行一个程序实例,并通过文件系统让这些实例进行同步。

3

使用进程而不是线程会有很大的不同——无论程序是否线程安全,它都能正常工作。当然,是否更快还要看解决问题所花的时间是否比额外的开销要大。

使用进程可能需要额外的麻烦来设置所有必要的数据。不过,multiprocessing模块可以处理大部分工作,所以这应该不会太难。

撰写回答