Python函数单核心正常多核心运行异常,如何正确利用多核心?
问题:joblib多核心运行时无法正确输出结果
我编写的Python函数在单核心(n_jobs=1)环境下运行正常,但设置n_jobs≠1使用多核心运行时结果错误。相关代码如下:
from joblib import Parallel, delayed import numpy as np import pandas as pd def foo(n_jobs): result = {} x = np.sin(4 * np.pi * np.arange(0, 1, 0.001)) y = np.sin(8 * np.pi * np.arange(0, 1, 0.001) + np.pi/2) x2yT = np.zeros(x.shape[0]) y2xT = np.zeros(x.shape[0]) def parallelize(ite): xi = x[ite] * 2 yi = y[ite] + 1 y2xT[ite] = xi x2yT[ite] = yi r = Parallel(n_jobs=n_jobs)(delayed(parallelize)(i) for i in np.arange(x.shape[0])) result[f'y2xT'] = y2xT result[f'x2yT'] = x2yT return pd.DataFrame(result)
单核心运行情况
运行代码:
r0 = foo(n_jobs=1) r0.plot()
结果图:单核心正常运行结果
多核心运行情况
运行代码:
r0 = foo(n_jobs=-1) r0.plot()
结果图:多核心运行异常结果
问题原因
joblib多核心模式下默认使用loky后端,子进程会复制父进程的内存空间。子进程对y2xT、x2yT数组的修改仅在自身进程内生效,不会同步到父进程,最终父进程拿到的还是初始的全0数组,导致结果错误。
修复方案
不要让子进程直接修改共享数组,改为让每个子进程返回计算结果,最后在父进程中统一合并数据。这种方式规避了进程间内存隔离的问题,同时能正确利用多核心。
修改后的代码:
from joblib import Parallel, delayed import numpy as np import pandas as pd def foo(n_jobs): x = np.sin(4 * np.pi * np.arange(0, 1, 0.001)) y = np.sin(8 * np.pi * np.arange(0, 1, 0.001) + np.pi/2) def parallelize(ite): xi = x[ite] * 2 yi = y[ite] + 1 return (ite, xi, yi) # 并行执行所有计算任务 results = Parallel(n_jobs=n_jobs)(delayed(parallelize)(i) for i in np.arange(x.shape[0])) # 初始化数组并填充计算结果 x2yT = np.zeros(x.shape[0]) y2xT = np.zeros(x.shape[0]) for ite, xi, yi in results: y2xT[ite] = xi x2yT[ite] = yi result = {'y2xT': y2xT, 'x2yT': x2yT} return pd.DataFrame(result)
优化说明
- 子进程仅负责计算并返回索引与对应值,不直接操作父进程的数组
- 父进程收集所有结果后统一填充数组,确保数据正确同步
- 该方式契合joblib多进程的设计逻辑,实现简单且可靠
若处理超大数组需要更高效的内存利用,可使用multiprocessing的共享内存对象(如RawArray),但实现复杂度较高,上述方案足以覆盖大多数场景。
内容的提问来源于stack exchange,提问作者lllIlllllIll
相关产品推荐
相关产品推荐

