You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何Python多进程CPU密集任务运行速度慢于单线程版本?

Python多进程处理CPU密集型任务反而更慢的原因分析

问题描述

我正在处理Python中的CPU密集型任务,尝试使用multiprocessing模块提升运行速度,原本预期通过并行执行获得性能提升,但实际多进程版本的运行速度明显慢于单线程版本。我使用multiprocessing.Pool结合map()方法在多个进程间分发任务,以下是简化后的代码:

from multiprocessing import Pool
import time

def compute(x):
    return sum(i * i for i in range(10_000))

if __name__ == '__main__':
    data = range(100)

    start = time.time()

    with Pool() as pool:
        results = pool.map(compute, data)

    print("Time with multiprocessing:", time.time() - start)

在不使用多进程的普通for循环中,相同逻辑的运行速度显著更快。我的设备配备8个CPU核心,请问导致该性能下降的原因是什么?是否与进程创建开销或数据序列化有关?

核心原因

你的情况确实和进程创建开销以及数据序列化/反序列化开销直接相关,具体拆解如下:

  • 单个任务计算量过小compute函数的计算逻辑非常简单,执行耗时极短。而多进程模式下,每个任务都要经历「参数序列化→发送到子进程→子进程执行→结果序列化→回传主进程」的流程,这些通信和调度的开销总和,已经远远超过了任务本身的计算时间,导致整体效率不如单线程循环。

  • 进程管理的额外开销Pool初始化时会创建与CPU核心数匹配的子进程(默认8个),进程的创建、系统调度本身就有固定开销,当任务总计算量不大时,这部分开销会成为性能瓶颈。

  • GIL并非问题根源:虽然Python的GIL会限制单线程的CPU利用率,但多进程是完全绕过GIL的,所以你的问题和GIL无关。

优化方案

  • 增大任务粒度:将多个小任务合并为大批次任务,减少任务分发和通信的次数。比如把100个任务分成8组(对应8个核心),让每个进程一次性处理一组数据,而非单个元素。

    修改后的示例代码:

    from multiprocessing import Pool
    import time
    
    def compute_batch(batch):
        return [sum(i * i for i in range(10_000)) for _ in batch]
    
    if __name__ == '__main__':
        data = range(100)
        # 拆分为8个批次
        batches = [data[i::8] for i in range(8)]
        
        start = time.time()
        with Pool() as pool:
            results = pool.map(compute_batch, batches)
        # 扁平化结果列表
        results = [item for sublist in results for item in sublist]
        print("Time with batched multiprocessing:", time.time() - start)
    
  • 调整进程池大小:过多的进程会增加调度开销,可尝试设置Pool(processes=4)这类小于核心数的进程数量,看是否能降低额外开销。

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

火山引擎 最新活动