Python多进程与Numba并行:大数组共享及函数编译问题咨询
问题解答
核心背景
- 正在学习Python多进程基础,现有一复杂函数:接收约1GB的只读大数组和
double类型参数,返回double值 - 目标:固定大数组,遍历约20个不同
double参数并行调用函数,寻找最优值 - 已用
@jit装饰器编译函数,获得性能提升,期望实现:- 每个进程不重复编译函数
- 各进程共享大数组,避免内存拷贝
测试场景说明
用户模拟了5种测试场景:
- 普通循环调用函数,无多进程、共享内存与JIT
- 普通循环调用JIT编译后的函数,无多进程与共享内存
- 多进程调用普通函数,无共享内存(曾出现结果与场景0不一致问题)
- 多进程调用JIT编译后的函数,无共享内存
- 多进程调用普通函数,使用共享内存(曾出现代码挂起,修改后可正常运行)
- 新增:基于numba parallel的测试场景(运行良好)
针对numba parallel的疑问解答
疑问1:使用numba parallel时,arg_vec会被拷贝到每个进程吗?
不会。numba的parallel模式(比如搭配prange使用)底层基于线程池(默认依赖OpenMP实现),并非真正的多进程。线程属于同一进程的内存空间,arg_vec这类数据只会存在一份,不会被拷贝到每个线程中。
如果arg_vec是numpy数组,numba会直接操作其底层内存;如果是Python原生容器(如列表),numba会转换为内部高效结构,但也不会在每个线程做完整拷贝。
疑问2:使用numba parallel时,test_func_jitted会在每个进程中重新编译吗?
不会。numba的JIT编译是进程级的:
- 第一次调用
test_func_jitted时,numba会在当前进程内完成编译,生成机器码并缓存 - numba parallel的线程属于同一个父进程,共享这份编译缓存,不会在每个线程中重复编译
- 只有用
multiprocessing这类真正创建新进程的方式时,才需要考虑子进程重新编译的问题(可通过提前编译、共享缓存或使用fork模式规避)
内容的提问来源于stack exchange,提问作者user415893
相关产品推荐
相关产品推荐

