我在python 3.7中使用多处理
一些文章说,在 Pool 中使用的进程数的一个很好的数字是 CPU 内核数。
我的 AMD 锐龙 CPU 有 8 个内核,可以运行 16 个线程。
那么,进程的数量应该是 8 个还是 16 个?
import multiprocessing as mp
pool = mp.Pool( processes = 16 ) # since 16 threads are supported?
问:">那么,进程数应该是 8 还是 16
?
因此,如果子进程分布式工作负载的群体是缓存重用密集型的(不是内存 I/O(,则SpaceDOMAIN
约束规则,因为可缓存数据的大小将在决定是 8 还是 16 时发挥主要作用。
为什么?
因为内存I/O的成本在TimeDOMAIN
中大约要贵一千倍,与缓存中数据的0.1 ~ 0.4 [ns]
相比,每个内存I/O支付约3xx - 4xx [ns]
。
如何做出决定?
在决定生产规模配置之前,先进行小规模测试。
因此,如果要分发的工作负载群是网络 I/O 或其他显着的(本地非单一(延迟来源,则TimeDOMAIN
可能会受益于执行延迟屏蔽技巧,运行 16、160 或仅运行 1600 个线程(在这种情况下不是进程(。
为什么?
因为执行网络 I/O 的成本提供了如此多的等待时间(几[ms]
的网络 I/O RTT 延迟足以为每个 CPU 核心 uop-s 做大约1E7 ~ 10.000.000
个,这是相当多的工作。因此,甚至整个进程的智能交错,这里也只使用延迟屏蔽的基于线程的并发处理可能适合(因为等待来自网络 I/O 的远程"答案"的线程不应该争取 GIL-lock,因为它们在收到预期的 I/O 字节之前没有什么可计算的,是吗?
如何做出决定?
查看代码以确定游戏中有多少通过网络 I/O 获取以及有多少关于缓存占用大小的读取(在 2020/Q2+ 中,L1 缓存增长到大约几[MB]
-s(。对于那些这些操作重复多次的情况,不要犹豫,为每个"慢速"网络 I/O 目标启动一个线程,因为处理将受益于巧合创建的"长"等待时间的掩码,代价只是便宜("快速"(和(由于"许多"和"长"等待时间(相当稀疏的线程切换,甚至是 O/S 驱动的进程调度程序将整个子进程映射到空闲的 CPU 内核上。
因此,如果要分发的工作负载群是上述情况的混合,那么除了在实际的硬件本地/非本地资源上进行试验之外,别无他法。
为什么?
因为没有经验法则可以微调工作负载处理到实际 CPU 核心资源的映射。
尽管如此,
人们可能很容易发现付出的代价比以往任何时候都
多 实现减速的已知陷阱
,而不是(只是希望获得(加速
在所有情况下,开销限制、资源感知和工作负载的原子性遵循修订后的阿姆达尔定律确定了收益递减点,之后任何更多的工作线程(CPU-core-s(都不会改善希望获得加速。获得 S <<1 的许多惊喜都在 Stack Overflow 帖子中表达,因此人们可以随心所欲地阅读不该做的事情(通过反模式学习(。