如何使用python找出CPU数量

我想知道使用Python的本地计算机上的CPU数量。 当使用最佳缩放的仅用户空间程序调用时,结果应该是user/realtime(1)所输出。


#1楼

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

如果您的Python版本> = 2.6,则可以简单地使用

import multiprocessing

multiprocessing.cpu_count()

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


#3楼

另一个选择是使用psutil库,该库在以下情况下总是有用的:

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

这应该可以在psutil支持的任何平台(Unix和Windows)上运行。

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


#4楼

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设计为可跨操作系统和体系结构移植。


#5楼

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

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

#6楼

在Python 3.4+中: os.cpu_count()

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


#7楼

您也可以为此目的使用“ 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()

#8楼

平台无关:

psutil.cpu_count(逻辑=假)

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


#9楼

无法弄清楚如何添加到代码或回复消息,但是这里提供了对jython的支持,您可以在放弃之前先加以支持:

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

#10楼

import os

print(os.cpu_count())

#11楼

这些给你超线程的CPU数量

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

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

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

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


#12楼

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

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

考虑到sched_setaffinity Linux系统调用os.sched_getaffinity(0) (在Python 3中添加)返回可用的CPU集,它限制了进程及其子进程可以在哪些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

使用测试脚本:

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对此非常明确:

打印可用的处理单元数

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

taskset -c 0 nproc --all

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

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


#13楼

这对于使用不同操作系统/系统但想要获得世界最佳状态的我们来说可能是有用的:

import os
workers = os.cpu_count()
if 'sched_getaffinity' in dir(os):
    workers = len(os.sched_getaffinity(0))
发布了0 篇原创文章 · 获赞 2 · 访问量 5923

猜你喜欢

转载自blog.csdn.net/asdfgh0077/article/details/104061234