如何找出使用python的CPU数量

时间:2009-06-17 10:41:44

标签: python system-information

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

16 个答案:

答案 0 :(得分:724)

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

import multiprocessing

multiprocessing.cpu_count()

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

答案 1 :(得分: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')

答案 2 :(得分:74)

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

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

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

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

答案 3 :(得分:36)

在Python 3.4+中:os.cpu_count()

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

答案 4 :(得分:26)

平台独立:

  

psutil.cpu_count(逻辑=假)

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

答案 5 :(得分:26)

import os

print(os.cpu_count())

答案 6 :(得分: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旨在跨操作系统和体系结构移植。

答案 7 :(得分:9)

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

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

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

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

另一方面,

multiprocessing.cpu_count()仅返回物理CPU的总数。

差异特别重要,因为某些群集管理系统(例如Platform LSF会通过sched_getaffinity限制作业CPU使用率。

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

通过使用taskset实用程序限制相似性,我们可以具体看到差异。

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

taskset -c 0 ./main.py

使用测试脚本:

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

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

答案 8 :(得分:7)

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

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

答案 9 :(得分: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()

答案 10 :(得分:4)

python 3.4以上版本可以使用

import os
os.cpu_count()

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

len(os.sched_getaffinity(0))

答案 11 :(得分:2)

如果您使用手电筒,您可以:

import torch.multiprocessing as mp

mp.cpu_count()

torch 中的 mp 库与主要的 Python 库具有相同的界面,因此您也可以像评论者提到的那样执行此操作:

python -c "import multiprocessing; print(multiprocessing.cpu_count())"

希望这有帮助! ;) 有超过 1 个选项总是好的。

答案 12 :(得分:1)

如果您没有Python 2.6,则另一个选择:

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

答案 13 :(得分:1)

这是来自多处理的函数cpu_count

:}

import os
import sys

def cpu_count():
    '''
    Returns the number of CPUs in the system
    '''
    if sys.platform == 'win32':
        try:
            num = int(os.environ['NUMBER_OF_PROCESSORS'])
        except (ValueError, KeyError):
            num = 0
    elif 'bsd' in sys.platform or sys.platform == 'darwin':
        comm = '/sbin/sysctl -n hw.ncpu'
        if sys.platform == 'darwin':
            comm = '/usr' + comm
        try:
            with os.popen(comm) as p:
                num = int(p.read())
        except ValueError:
            num = 0
    else:
        try:
            num = os.sysconf('SC_NPROCESSORS_ONLN')
        except (ValueError, OSError, AttributeError):
           num = 0

    if num >= 1:
        return num
    else:
        raise NotImplementedError('cannot determine number of cpus')

答案 14 :(得分:1)

由于我无法发表评论:

这些为您提供了“物理” CPU计数

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

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

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

只有在虚拟机上工作才重要。

答案 15 :(得分:1)

这可能适合那些使用不同操作系统/系统,但又想获得世界最佳水平的人:

import os
workers = os.cpu_count()
if 'sched_getaffinity' in dir(os):
    workers = len(os.sched_getaffinity(0))