You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Python多进程开销过高、新增核心耗时反而上升的问题

问题成因
  • 核心原因是高频访问multiprocessing.Manager创建的共享字典:Manager的共享对象实际存储在独立的管理进程中,所有子进程对该对象的读取、遍历操作都需要跨进程IPC通信,且默认加锁避免并发冲突。你的代码在循环中反复遍历共享字典的values(),进程数越多,IPC请求和锁竞争越严重,通信开销远超过计算本身的开销,导致耗时随核心数上升。
  • 次要问题1:jobs列表未重置,每次测试不同进程数时,都会把新进程追加到原有列表中,join操作会遍历所有历史进程,增加无意义开销。
  • 次要问题2:总计算量过小,单进程完成全部计算的耗时本身就极低,多进程的启动、通信开销直接覆盖了并行收益。
优化方案
  1. 只读数据避免使用共享对象:你的mp_dict是只读的,不需要跨进程同步修改,直接将普通字典作为参数传给子进程,子进程会自动拿到副本,完全避免IPC开销。
  2. 每次测试前重置jobs列表,避免累加历史进程。
  3. 减少共享对象的使用:返回结果可通过multiprocessing.Pool的map系列方法直接获取,不需要用Manager.dict存储返回值。
  4. 合理控制任务粒度:如果实际业务的单任务计算量很小,可合并多个小任务为一个大任务再分配给进程,保证计算耗时远大于进程通信开销。
优化后代码示例
import time
import multiprocessing as mp
import numpy as np

def test_fun(args):
    iter_nr, local_dict = args
    dumm = 0
    for j in range(iter_nr):
        for val in local_dict.values():
            dumm += val
    return dumm

if __name__ == '__main__':
    # 构造普通只读字典,不需要共享
    local_dict = {str(i):1 for i in range(100)}
    nproc = [2,4,6,8,10,12,16,20]
    nr_iter = 2*4*6*8*10
    print('Total number of iterations: ', nr_iter)

    for n_proc in nproc:
        per_proc_iter = int(nr_iter / n_proc)
        print('Nr CPUs: ', n_proc)
        print('Nr iterations per process: ', per_proc_iter)
        # 构造进程池的任务参数
        tasks = [(per_proc_iter, local_dict) for _ in range(n_proc)]
        start_time = time.time()
        with mp.Pool(n_proc) as pool:
            res = pool.map(test_fun, tasks)
        end_time = time.time()
        print(round(end_time - start_time, 3), 'sec')

优化后运行耗时会随核心数增加明显下降,符合并行计算预期。

内容的提问来源于stack exchange,提问作者Jaro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 22:36:04