如何使Python的多进程生成以使用所有可用的CPU

时间:2017-02-24 13:31:24

标签: python amazon-ec2 multiprocessing

我的AWS实例有32个CPUS:

ubuntu@ip-122-00-18-114:~$ cat /proc/cpuinfo  | grep processor  | wc -l
32

我的问题是如何使用Python的multiprocessing 这样每个命令都会在每个CPU上运行。

例如,使用以下代码,每个命令都会在每个可用的CPU上运行吗?

import multiprocessing
import os
POOL_SIZE = 32
cmdlist = []
for param in items:
    cmd = """./cool_command %s""" % (param)
    cmdlist.append(cmd)
p = multiprocessing.Pool(POOL_SIZE)
p.map(os.system, cmdlist)

如果没有,那么正确的做法是什么?

如果我设置POOL_SIZE>会发生什么? #处理器(CPU)?

2 个答案:

答案 0 :(得分:2)

首先对你的措辞进行一点修改。 CPU具有不同的核心,每个核心都有超线程。每个超线程都是运行处理器的逻辑单元。在亚马逊上,您有32个vCPU,它们对应于超线程,而不是CPU或核心。这对于这个问题并不重要,但是如果你进行任何进一步的研究,重要的是要有正确的措辞。我将高速线程的“最低逻辑处理单元”称为vCPU

如果您未指定池大小:

p = multiprocessing.Pool()
p.map(os.system, cmdlist)

然后python会找出可用逻辑处理器的数量(在你的情况下是32个vCPU)本身(通过os.cpu_count())。

在正常情况下,所有32个进程都在单独的vCPU上运行,因为Linux尝试在它们之间平衡负载。 但是,如果同时运行其他重型进程,则可能会在同一个vCPU上运行两个进程。

这里要理解的关键是Linux调度程序的工作原理:它会定期重新安排进程,以便对所有处理单元的使用情况大致相同。这意味着如果您只启动16个进程,那么它们将分散到所有32个vCPU并使用它们相同(使用htop查看负载如何传播)。

  

如果我设置POOL_SIZE>会发生什么? #处理器(CPU)?

如果您启动的进程多于可用的vCPU,则有些进程需要共享vCPU。这意味着调度程序在上下文切换中定期切换进程。如果您的进程受CPU限制(使用100%cpu,例如当您执行数字运算时),那么拥有比vCPU更多的进程将减慢整个进程,因为您将使上下文切换速度变慢并且如果您在进程之间进行通信(不是在你的例子中,而是在进行多处理时通常会做的事情),这也会减慢。

然而。如果您的进程不受CPU限制,例如磁盘绑定(需要等待磁盘进行读/写)或网络绑定(例如,等待其他服务器应答)然后由调度程序将它们切换为另一个进程腾出空间,因为它们无论如何都需要等待。

答案 1 :(得分:0)

简单的问题是“不完全”。您可以使用os.cpu_count()函数获取cpu计数并运行此数量的进程。但只有操作系统将进程分配给CPU。而且不止于此 - 它可能会在一段时间内将其切换到另一个cpu。我不会解释preemptive multitasking如何在这里工作。

如果您在此服务器上运行其他“繁重”进程 - 例如数据库甚至Web服务器 - 他们可能还需要一些CPU时间来执行它们。

一些好消息是存在一个名为Process Affinity的东西,可以满足您的需求。但它是一种微调操作系统。