如何找出使用python的CPU数量

phi*_*hag 477 python system-information

我想知道使用Python的本地机器上的CPU数量.当使用最佳扩展用户空间程序调用时,结果应该是user/real输出time(1).

Nad*_*mli 784

如果你有一个版本> = 2.6的python你可以简单地使用

import multiprocessing

multiprocessing.cpu_count()
Run Code Online (Sandbox Code Playgroud)

http://docs.python.org/library/multiprocessing.html#multiprocessing.cpu_count

  • 在Python 3.6.2上,我只能使用`os.cpu_count()` (13认同)
  • 此外,如下所述,此计数可能包括“虚拟”超线程 CPU,如果您正在调度 CPU 密集型任务,这可能不是您想要的。 (10认同)
  • 3.x还支持多处理 (3认同)
  • 我想补充一点,这在IronPython中不起作用,这会引发NotImplementedError. (3认同)
  • 这给出了可用的 CPU 数量……程序未使用! (3认同)
  • @Casey是的,确实如此,使用sysctl -n. (2认同)
  • @SamyBencherif 这是上面提到的结果。“超线程”导致操作系统的物理处理器核心数量增加一倍 (2认同)
  • 除了超线程 cpu 之外,“multiprocessing.cpu_count()”不考虑通过“docker run --cpus=2”对 CPU 使用的限制。 (2认同)

phi*_*hag 172

如果您对当前进程可用的处理器数量感兴趣,则必须先检查cpuset.否则(或者如果没有使用cpuset),multiprocessing.cpu_count()是Python 2.6及更高版本的方法.以下方法回溯到旧版Python中的几种替代方法:

import os
import re
import subprocess


def available_cpu_count():
    """ Number of available virtual or physical CPUs on this system, i.e.
    user/real as output by time(1) when called with an optimally scaling
    userspace-only program"""

    # cpuset
    # cpuset may restrict the number of *available* processors
    try:
        m = re.search(r'(?m)^Cpus_allowed:\s*(.*)$',
                      open('/proc/self/status').read())
        if m:
            res = bin(int(m.group(1).replace(',', ''), 16)).count('1')
            if res > 0:
                return res
    except IOError:
        pass

    # Python 2.6+
    try:
        import multiprocessing
        return multiprocessing.cpu_count()
    except (ImportError, NotImplementedError):
        pass

    # https://github.com/giampaolo/psutil
    try:
        import psutil
        return psutil.cpu_count()   # psutil.NUM_CPUS on old versions
    except (ImportError, AttributeError):
        pass

    # POSIX
    try:
        res = int(os.sysconf('SC_NPROCESSORS_ONLN'))

        if res > 0:
            return res
    except (AttributeError, ValueError):
        pass

    # Windows
    try:
        res = int(os.environ['NUMBER_OF_PROCESSORS'])

        if res > 0:
            return res
    except (KeyError, ValueError):
        pass

    # jython
    try:
        from java.lang import Runtime
        runtime = Runtime.getRuntime()
        res = runtime.availableProcessors()
        if res > 0:
            return res
    except ImportError:
        pass

    # BSD
    try:
        sysctl = subprocess.Popen(['sysctl', '-n', 'hw.ncpu'],
                                  stdout=subprocess.PIPE)
        scStdout = sysctl.communicate()[0]
        res = int(scStdout)

        if res > 0:
            return res
    except (OSError, ValueError):
        pass

    # Linux
    try:
        res = open('/proc/cpuinfo').read().count('processor\t:')

        if res > 0:
            return res
    except IOError:
        pass

    # Solaris
    try:
        pseudoDevices = os.listdir('/devices/pseudo/')
        res = 0
        for pd in pseudoDevices:
            if re.match(r'^cpuid@[0-9]+$', pd):
                res += 1

        if res > 0:
            return res
    except OSError:
        pass

    # Other UNIXes (heuristic)
    try:
        try:
            dmesg = open('/var/run/dmesg.boot').read()
        except IOError:
            dmesgProcess = subprocess.Popen(['dmesg'], stdout=subprocess.PIPE)
            dmesg = dmesgProcess.communicate()[0]

        res = 0
        while '\ncpu' + str(res) + ':' in dmesg:
            res += 1

        if res > 0:
            return res
    except OSError:
        pass

    raise Exception('Can not determine number of CPUs on this system')
Run Code Online (Sandbox Code Playgroud)

  • os.cpu_count() (3认同)
  • `open('/proc/self/status').read()` 忘记关闭文件。使用 `with open('/proc/self/status') as f: f.read()` 代替 (2认同)

Bak*_*riu 82

另一个选择是使用psutil库,在这些情况下总是有用:

>>> import psutil
>>> psutil.cpu_count()
2
Run Code Online (Sandbox Code Playgroud)

这应该适用于psutil(Unix和Windows)支持的任何平台.

请注意,在某些情况下multiprocessing.cpu_count可能会产生一种NotImplementedError同时psutil就能获得CPU的数量.这只是因为psutil首先尝试使用相同的技术multiprocessing,如果失败,它也会使用其他技术.

  • 这个真的很好,考虑到所使用的方法可以找出CPU核心是逻辑核心还是物理核心。`psutil.cpu_count(逻辑 = True)` (6认同)
  • @Devilhunter 在我的 Intel i7-8700 上的 Windows 上,`psutil.cpu_count()` 给出了 12(这是一个带有超线程的 6 核 CPU)。这是因为“逻辑”的默认参数为 True,因此您明确需要编写“psutil.cpu_count(逻辑= False)”来获取物理核心数。 (2认同)
  • 我相信“psutil.Process().cpu_affinity()”是大多数用户想要的,解释如下:/sf/answers/3879621931/ BTW。 (2认同)

jfs*_*jfs 43

在Python 3.4+中:os.cpu_count().

multiprocessing.cpu_count()是根据此函数实现的,但NotImplementedError如果os.cpu_count()返回则会引发None("无法确定CPU的数量").

  • 另请参见`cpu_count`的文档。len(os.sched_getaffinity(0))可能更好,这取决于目的。 (3认同)
  • @Albert是的,系统中的CPU数量(“os.cpu_count()”——OP所要求的)可能与当前进程可用的CPU数量(“os.sched_getaffinity(0)”)不同。 (3认同)

Dav*_*jad 30

平台独立:

psutil.cpu_count(逻辑=假)

https://github.com/giampaolo/psutil/blob/master/INSTALL.rst

  • 逻辑是'模拟cpu':https://en.wikipedia.org/wiki/Hyper-threading (5认同)
  • @user305883假设你有一个x86 CPU,你在这台机器上有[超线程](https://en.wikipedia.org/wiki/Hyper-threading),即每个物理核心对应两个超线程(“逻辑”核心)。当线程 A 的部分空闲(例如,等待从高速缓存或内存中获取数据)时,超线程允许使用物理核心来执行线程 B 的指令。根据您的代码,人们可以获得百分之一或百分之几十的额外核心利用率,但它远远低于真实物理核心的性能。 (5认同)
  • 逻辑CPU有什么区别而不是逻辑CPU?在我的笔记本电脑上:`psutil.cpu_count(logical = False)#4``psutil.cpu_count(logical = True)#8`和`multiprocessing.cpu_count()#8` (4认同)

Cir*_*四事件 24

len(os.sched_getaffinity(0)) 通常就是你想要的

https://docs.python.org/3/library/os.html#os.sched_getaffinity

os.sched_getaffinity(0)(在Python 3中添加)(考虑sched_setaffinityLinux系统调用)返回可用的CPU集合,这限制了进程及其子进程可以在哪些CPU上运行。

0表示获取当前过程的值。该函数返回set()允许的CPU,因此需要len()

multiprocessing.cpu_count() 另一方面,仅返回物理CPU的总数。

这种差异尤为重要,因为某些集群管理系统(例如Platform LSF)将作业CPU的使用限制为sched_getaffinity

因此,如果使用multiprocessing.cpu_count(),则脚本可能会尝试使用比可用内核更多的内核,这可能导致过载和超时。

通过限制与taskset实用程序的关联性,我们可以具体看到差异。

例如,如果我在16核系统中将Python限制为仅1核(0核):

taskset -c 0 ./main.py
Run Code Online (Sandbox Code Playgroud)

使用测试脚本:

main.py

#!/usr/bin/env python3

import multiprocessing
import os

print(multiprocessing.cpu_count())
print(len(os.sched_getaffinity(0)))
Run Code Online (Sandbox Code Playgroud)

那么输出是:

16
1
Run Code Online (Sandbox Code Playgroud)

nproc 但是默认情况下确实遵守关联性,并且:

taskset -c 0 nproc
Run Code Online (Sandbox Code Playgroud)

输出:

1
Run Code Online (Sandbox Code Playgroud)

man nproc使其非常明确:

打印可用的处理单元数

nproc具有--all要获取物理CPU计数的较不常见情况的标志:

taskset -c 0 nproc --all
Run Code Online (Sandbox Code Playgroud)

该方法的唯一缺点是,它似乎仅适用于UNIX。我以为Windows必须具有类似的相似性API SetProcessAffinityMask,所以我想知道为什么还没有移植它。但是我对Windows一无所知。

已在Ubuntu 16.04,Python 3.5.2中进行了测试。

  • 在 macOS 上:`AttributeError:'Process' 对象没有属性 'cpu_affinity'` (3认同)
  • 仅在Unix上可用。 (2认同)
  • 适用于 jupyter 笔记本! (2认同)
  • 对于计算节点可能有 48 个核心但您只请求其中 10 个的 HPC 情况,此解决方案也是必要的。os.cpu_count() 会告诉你有 48 个核心,但正如@CiroSantilli郝海东冠状病六四事件法轮功所说,如果你尝试使用它,你会遇到各种各样的问题。os.sched_getaffinity(0) 将报告调度程序实际请求的内容,例如。公共广播公司 (2认同)
  • @Anentropic 感谢您提供此信息,真是可惜。mac 用户也必须研究 `psutil` 和 stdlib 的上游,然后看起来:-) (2认同)

Dou*_*ple 19

multiprocessing.cpu_count()将返回逻辑CPU的数量,因此如果您有一个具有超线程的四核CPU,它将返回8.如果你想要物理CPU的数量,使用python绑定到hwloc:

#!/usr/bin/env python
import hwloc
topology = hwloc.Topology()
topology.load()
print topology.get_nbobjs_by_type(hwloc.OBJ_CORE)
Run Code Online (Sandbox Code Playgroud)

hwloc旨在跨操作系统和体系结构移植.

  • 或者`psutil.cpu_count(logical = False)` (6认同)

yan*_*iu2 13

这些给你超线程的CPU数量

  1. multiprocessing.cpu_count()
  2. os.cpu_count()

这些为您提供虚拟机的CPU数量

  1. psutil.cpu_count()
  2. numexpr.detect_number_of_cores()

仅在您在VM上工作时才重要。

  • 是。我改写了。通常是内核数x2。我的意思是,如果您在虚拟机上划分出8个内核,但是主机物理上是20个内核,则第一组命令给您20,第二组命令给您8。 (2认同)

Kon*_*hog 9

这可能适用于我们这些使用不同操作系统/系统,但想要充分利用所有世界的人:

import os
workers = os.cpu_count()
if 'sched_getaffinity' in dir(os):
    workers = len(os.sched_getaffinity(0))
Run Code Online (Sandbox Code Playgroud)


Ben*_*rey 7

无法弄清楚如何添加到代码或回复消息,但这里支持jython,你可以放弃之前放弃:

# jython
try:
    from java.lang import Runtime
    runtime = Runtime.getRuntime()
    res = runtime.availableProcessors()
    if res > 0:
        return res
except ImportError:
    pass
Run Code Online (Sandbox Code Playgroud)


小智 6

对于 3.4 以上的 python 版本,您可以使用

import os
os.cpu_count()
Run Code Online (Sandbox Code Playgroud)

如果您正在寻找等效的 linux 命令nproc。你有这个选项

len(os.sched_getaffinity(0))
Run Code Online (Sandbox Code Playgroud)


ami*_*690 5

您也可以为此目的使用“ joblib”。

import joblib
print joblib.cpu_count()
Run Code Online (Sandbox Code Playgroud)

此方法将为您提供系统中的cpus数。但是需要安装joblib。关于joblib的更多信息可以在这里找到 https://pythonhosted.org/joblib/parallel.html

或者,您可以使用python的numexpr软件包。它具有许多简单的功能,有助于获取有关系统cpu的信息。

import numexpr as ne
print ne.detect_number_of_cores()
Run Code Online (Sandbox Code Playgroud)