python - 为什么在 Pool 中使用超过 2 个进程后没有影响?
问题描述
通过使用库中的map函数,multiprocessing
我发现使用超过 2 个进程时执行时间没有差异。我正在使用 4 个内核运行程序。
实际代码非常简单,计算前 4000 个斐波那契数 4 次(= 核心数量)。它在 N 个核心之间平均分配工作(例如,当使用具有 2 个进程的池时,每个进程将计算前 4000 个斐波那契数两次)。整个过程是针对 N = 1 完成的,直到内核数量。
输出,每行中的核心数量和相应的执行时间(以秒为单位)是:
- 3,147
- 1,72
- 1,896
- 1.899
有谁知道为什么在超过 2 个内核的情况下执行时间没有减少?实际代码是:
import multiprocessing
from time import time
def F(_):
for n in range(4 * 10 ** 3):
a, b = 0, 1
for i in range(0, n):
a, b = b, a + b
return
def pool_fib():
n_cores = multiprocessing.cpu_count()
args = list(range(multiprocessing.cpu_count()))
for i in range(1, n_cores + 1):
with multiprocessing.Pool(i) as p:
start = time()
p.map(F, args)
print(i, time() - start)
if __name__ == '__main__':
pool_fib()
解决方案
如果您使用的是相当现代的 CPU,multiprocessing.cpu_count()
则不会给您机器拥有的物理内核数,而是超线程数。简而言之,超线程允许单个物理内核拥有n
(最常见的是两个)管道,这会使您的操作系统误以为您拥有n
的内核数量是您实际拥有的内核数量的倍数。这很有帮助,当您正在做一些可能使核心数据匮乏的事情(最明显的是,由缓存未命中引起的 IO 或 RAM 查找),但您的工作负载是纯算术的,它不太可能使您的 CPU 挨饿,从而导致超线程几乎没有收益。您可能获得的一点点收益将被多处理开销所掩盖,这是非常重要的。
附言
我通常将这类东西作为评论发布,但我已经超出了评论大小的限制。顺便说一句,如果您选择斐波那契数列不仅仅是一个示例,您可能需要考虑一种更快的算法:快速斐波那契计算
推荐阅读
- java - 如何将编辑后的文本文件保存在 JTextArea 中?
- node.js - 快速护照检查用户是否已通过身份验证
- sql-server - SQL Server VS 需要将我的数据库转储到 bak 文件
- c# - C#项目中file.SaveAs(filePath)无限制上传文件危险类型的静态代码分析问题
- android - Unity - Project 中的 .txt 文件隐藏在 .apk 中?
- javascript - 解析 ABI 文件以获取方法签名
- java - ElasticSearch - 带有 scrollAPI 的 RestHighLevelClient 抛出`Suppressed: org.apache.http.ContentTooLongException: entity content is too long`
- angular - flex 容器和 ngIf 水平居中
- dart - Flutter - 从孩子更新父状态
- dart - 回调函数在颤动中不起作用