如何找出使用python的CPU数量

问题描述 投票:429回答:12

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

python system-information
12个回答
732
投票

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

import multiprocessing

multiprocessing.cpu_count()

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


4
投票

您也可以使用“joblib”来实现此目的。

import joblib
print joblib.cpu_count()

此方法将为您提供系统中的cpus数。但是需要安装joblib。有关joblib的更多信息,请访问https://pythonhosted.org/joblib/parallel.html

或者你可以使用python的numexpr包。它有很多简单的函数,有助于获取有关系统CPU的信息。

import numexpr as ne
print ne.detect_number_of_cores()

4
投票

这些为您提供超线程的CPU数量

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

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

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

只有在虚拟机上工作才有意义。


1
投票

如果你没有Python 2.6,另一种选择:

import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")

164
投票

如果您对当前流程可用的处理器数量感兴趣,则必须先检查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')

76
投票

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

>>> import psutil
>>> psutil.cpu_count()
2

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

请注意,在某些情况下,multiprocessing.cpu_count可能会提高NotImplementedError,而psutil将能够获得CPU的数量。这只是因为psutil首先尝试使用multiprocessing使用的相同技术,如果失败,它还使用其他技术。


36
投票

在Python 3.4+中:os.cpu_count()

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


27
投票
import os

print(os.cpu_count())

26
投票

平台独立:

psutil.cpu_count(逻辑=假)

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


16
投票

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)

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


10
投票

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

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

os.sched_getaffinity(0)(在Python 3中添加)返回可用的CPU集合,考虑到sched_setaffinity Linux system call,它限制进程及其子进程可以运行的CPU。

0意味着获得当前流程的价值。该函数返回允许的CPU的set(),因此需要len()

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

差异尤为重要,因为某些集群管理系统(如Platform LSF)会限制使用sched_getaffinity的CPU使用率。

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

我们可以通过限制与taskset实用程序的亲和力来具体看到差异。

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

taskset -c 0 ./main.py

使用测试脚本:

卖弄.朋友

#!/usr/bin/env python3

import multiprocessing
import os

print(multiprocessing.cpu_count())
print(len(os.sched_getaffinity(0)))

然后输出是:

16
1

nproc默认尊重亲和力:

taskset -c 0 nproc

输出:

1

man nproc使这一点非常明确:

打印可用的处理单元数

nproc有一个--all标志,用于您想要获得物理CPU数量的不太常见的情况:

taskset -c 0 nproc --all

这种方法的唯一缺点是它似乎只是UNIX。我认为Windows必须有一个类似的亲和力API,可能是SetProcessAffinityMask,所以我想知道它为什么没有被移植。但我对Windows一无所知。

在Ubuntu 16.04,Python 3.5.2中测试。


7
投票

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

# jython
try:
    from java.lang import Runtime
    runtime = Runtime.getRuntime()
    res = runtime.availableProcessors()
    if res > 0:
        return res
except ImportError:
    pass
© www.soinside.com 2019 - 2024. All rights reserved.