如何用Python multiprocessing加速CPU密集型嵌套循环并满足并行要求
队列版本耗时过高的原因
- 大量跨进程同步开销:你使用了
multiprocessing.Manager管理的共享字典、共享计数器、条件变量,所有add/done/wait操作都需要走跨进程IPC通信,本身开销远高于你定义的CPU密集型任务,叠加1010100=10000次的同步操作,直接吃掉了所有并行收益。 - 任务拆分粒度过细:你将每一次
cpu_bound_task都拆成独立的队列任务,每次任务分发都需要经历参数序列化、队列传输、反序列化的过程,额外开销被放大了上万倍。 - 人为限制并行度:你给第二层循环对应的WaitGroup设置了
max_p=1,导致第二层循环完全串行执行,完全没有用到多进程的并行能力。 - 进程数设置不合理:你启动了10个工作进程,CPU密集型场景下进程数超过CPU核心数会带来大量上下文切换开销,进一步拖慢性能。
满足需求的最优实现方案
你的两个需求可以直接通过双层进程池实现,完全不需要自己实现WaitGroup和队列调度,代码更简洁,性能也远高于自定义队列版本:
首先定义单次第一层循环的处理逻辑:
import os from multiprocessing import Pool def cpu_bound_task(): _ = [0]*1000000 def process_single_i(i): # 对应第一层循环i的单次迭代逻辑 cpu_bound_task() # 复用内层进程池减少创建销毁开销 with Pool(processes=os.cpu_count()) as inner_pool: for j in range(10): cpu_bound_task() # 内层100次CPU任务并行 inner_pool.map(cpu_bound_task, range(100)) return
主函数实现满足两个要求:
def main_opt(): total_i = 10 # 原第一层循环的迭代次数 # 外层池固定3个进程,满足第一层3个并行的要求 with Pool(processes=3) as outer_pool: # 按3个一批提交任务,每批执行完成再进入下一批,满足迭代等待要求 for batch_idx in range(0, total_i, 3): current_batch = range(batch_idx, min(batch_idx+3, total_i)) # 提交当前批次所有任务 async_results = [outer_pool.apply_async(process_single_i, args=(i,)) for i in current_batch] # 等待当前批次所有任务执行完成 for res in async_results: res.get()
这个方案的性能会远高于你的自定义队列版本,甚至比你原有仅内层并行的进程池版本性能更高,因为减少了进程池重复创建销毁的开销。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

