使用SciPy.optimize进行并行计算
我正在做一些研究代码,使用 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%,所以这对我来说没什么用。
我的问题是,我该怎么办呢?我觉得我的选择有:
- 找一个线程安全的LM实现(也许是levmar?)
- 尝试使用进程而不是线程(我觉得这可能没什么区别)
任何帮助或建议都非常感谢。
2 个回答
-1
你有多少个CPU或核心?如果你的程序在运行时已经占满了100%的资源,但没有使用多线程,那就没有什么好处可言。如果leastq()
这个函数不是线程安全的,而且你没有把电脑的资源用到极限,那么你可以在每个核心上运行一个程序实例,并通过文件系统让这些实例进行同步。
3
使用进程而不是线程会有很大的不同——无论程序是否线程安全,它都能正常工作。当然,是否更快还要看解决问题所花的时间是否比额外的开销要大。
使用进程可能需要额外的麻烦来设置所有必要的数据。不过,multiprocessing
模块可以处理大部分工作,所以这应该不会太难。