You need to enable JavaScript to run this app. Python中用multiprocessing做素数计算,为何没用到全部CPU核心?
优惠活动
大模型
产品
解决方案
定价
更多

Python中用multiprocessing做素数计算,为何没用到全部CPU核心?

核心问题根源

导致性能完全没有提升的最核心原因,是代码导入的根本不是真的多进程实现:

  • 代码中写的导入语句是from multiprocessing.dummy import Pool,这个dummy模块是Python为了统一多进程/多线程API做的线程封装层,本质是基于threading实现的多线程池,全程没有创建独立的操作系统进程,仍然受Python GIL的严格约束。
  • 这种实现下,哪怕设置了12个线程,在CPU密集型的素数计算场景中,同一时刻永远只有一个线程能获得Python解释器的执行权,根本没法实现真的并行计算。你观测到的“多进程运行时CPU占用12%、单线程运行时CPU占用10%”的现象,正好匹配12逻辑线程的CPU只跑满1个线程算力的特征——单线程纯计算的CPU占用大概在8%~10%,和实测数值完全吻合。

需要澄清一个常见认知误区:multiprocessing确实可以绕过GIL实现多核并行,但前提是使用原生的multiprocessing进程池,而不是带dummy标识的线程兼容版本。

代码中影响并行效率的其他细节问题

哪怕修正导入语句,当前代码还有几个会拉低并行收益的问题:

  • 无分块的pool.map(prime, loop)模式任务粒度过小:每个任务仅需判断一个数是不是素数,进程间通信需要对每个任务做序列化、传递、反序列化,当计算收益远低于通信开销时,并行带来的提升会被完全抵消。
  • 进程池大小硬编码为12:对于CPU密集型任务,过多的进程会带来不必要的上下文切换开销,一般进程数设置为物理核心数时效率最高。6核CPU对应开6个工作进程就足够,超线程的逻辑核心对纯计算任务的提升非常有限。
  • 短时间单次测试的误差:Python多进程在Windows系统下默认用spawn模式启动,首次创建进程池时需要全量序列化主进程代码、创建独立内存空间,这个固定开销会被100万次素数计算的短测试放大,多次重复取平均的测试结果才会更准确。
正确的多核并行实现步骤

要获得预期的并行性能提升,按照以下方式调整即可:

  1. 替换导入语句,去掉dummy标识:将from multiprocessing.dummy import Pool改为from multiprocessing import Pool,这样创建的才是拥有独立内存空间、完全绕开GIL的真进程池。
  2. 保留已实现的分块逻辑:把连续的一段待计算数字打包为一个任务传给子进程,减少进程间通信的次数。当单个任务包含几千到上万次素数判断时,通信开销的占比会降到可忽略的水平。
  3. 动态设置进程池大小:用cpu_count()获取系统核心数,根据物理核心数调整工作进程数量,避免无意义的资源浪费。

按照上述调整后,在6核CPU上跑素数计算,能获得接近6倍的单线程性能提升,任务管理器也会观测到接近100%的整体CPU占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 16:54:03