Scipy differential_evolution设workers后未多核运行且耗时更长求助
Scipy differential_evolution并行化优化问题解决
问题背景
想要通过workers参数让Scipy的differential_evolution函数实现多核运行,按照官方文档编写了对比脚本,分别测试workers=1(无并行)和workers=10(搭配updating='deferred')的运行耗时,但并行版本耗时反而更长。
测试脚本
import time if __name__ == '__main__': from scipy.optimize import differential_evolution, rosen bounds = [( 0, 2 ), ( 0, 2 ), ( 0, 2 ), ( 0, 2 ), ( 0, 2 )] print( 'Beginning optimisation without parallelisation' ) start = time.time() result = differential_evolution( rosen, bounds, workers=1, popsize=200, maxiter=1000, tol=0.001, seed=1 ) end = time.time() print( 'Optimisation finished after {} seconds'.format( round( end - start, 2 ) ) ) print( '\nBeginning optimisation with workers parameter set to 10' ) start = time.time() result = differential_evolution( rosen, bounds, updating='deferred', workers=10, popsize=200, maxiter=1000, tol=0.001, seed=1 ) end = time.time() print( 'Optimisation finished after {} seconds'.format( round( end - start, 2 ) ) )
运行结果
Beginning optimisation without parallelisation Optimisation finished after 59.0 seconds Beginning optimisation with workers parameter set to 10 Optimisation finished after 60.43 seconds
当前环境:Python 3.8、Scipy 1.8.1
问题原因与解决方法
核心原因
并行版本耗时更长,本质是目标函数计算量过小,并行带来的进程通信、调度开销超过了计算节省的时间:
- 你用的Rosenbrock函数在5维变量下计算极快,每个个体的目标函数求值几乎瞬间完成,而启动多进程、传递数据、进程间同步的时间远大于并行计算节省的时间。
- 设置
workers=10可能超过了你的CPU物理核心数,导致进程频繁切换,进一步增加额外开销。
正确实现并行化的建议
- 提升目标函数计算量:
要么增加变量维度(比如改成20维甚至更高),要么在自定义目标函数中加入耗时逻辑(比如矩阵运算、循环迭代),让每个个体的计算时间足够长,才能体现并行的优势。 - 合理设置workers数量:
建议将workers设为CPU物理核心数(可通过os.cpu_count()获取),不要超过这个数值,避免进程切换带来的额外开销。 - 优化任务分配:
将popsize设置为workers的整数倍,保证每个worker能分配到均匀的任务量,减少空闲等待时间。
优化后的示例代码
import time import os if __name__ == '__main__': from scipy.optimize import differential_evolution, rosen # 提升变量维度到20,增加目标函数计算量 bounds = [(0, 2)] * 20 # 获取CPU物理核心数 core_count = os.cpu_count() print('无并行优化开始') start = time.time() result = differential_evolution(rosen, bounds, workers=1, popsize=200, maxiter=1000, tol=0.001, seed=1) end = time.time() print(f'无并行优化完成,耗时 {round(end - start, 2)} 秒') print(f'\n使用 {core_count} 个workers并行优化开始') start = time.time() result = differential_evolution(rosen, bounds, updating='deferred', workers=core_count, popsize=200, maxiter=1000, tol=0.001, seed=1) end = time.time() print(f'并行优化完成,耗时 {round(end - start, 2)} 秒')
内容的提问来源于stack exchange,提问作者RJ-mac
相关产品推荐
相关产品推荐

