如何使用python查找CPU的数量
我想知道本地机器上使用Python的CPU数量。当使用仅限用户空间的最佳缩放程序调用时,结果应为如何使用python查找CPU的数量,python,system-information,Python,System Information,我想知道本地机器上使用Python的CPU数量。当使用仅限用户空间的最佳缩放程序调用时,结果应为user/real,作为time(1)的输出。如果您对当前进程可用的处理器数量感兴趣,您必须先检查。否则(或者如果没有使用cpuset),这是Python2.6及更新版本的发展方向。以下方法可以追溯到Python旧版本中的两种替代方法: import os import re import subprocess def available_cpu_count(): """ Number o
user/real
,作为time(1)
的输出。如果您对当前进程可用的处理器数量感兴趣,您必须先检查。否则(或者如果没有使用cpuset),这是Python2.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.6的python,只需使用
import multiprocessing
multiprocessing.cpu_count()
不知道如何添加代码或回复消息,但以下是对jython的支持,您可以在放弃之前加入:
# jython
try:
from java.lang import Runtime
runtime = Runtime.getRuntime()
res = runtime.availableProcessors()
if res > 0:
return res
except ImportError:
pass
另一种选择是使用库,它在以下情况下总是很有用:
>>> import psutil
>>> psutil.cpu_count()
2
这应该适用于psutil(Unix和Windows)支持的任何平台
请注意,在某些情况下,
多处理。cpu\u计数
可能会引发未实现错误
,而psutil
将能够获取cpu数量。这仅仅是因为psutil
首先尝试使用与多处理
相同的技术,如果这些技术失败,它还会使用其他技术。多处理。cpu_count()
将返回逻辑cpu的数量,因此如果您有一个带超读功能的四核cpu,它将返回8
。如果需要物理CPU的数量,请使用与hwloc的python绑定:
#!/usr/bin/env python
import hwloc
topology = hwloc.Topology()
topology.load()
print topology.get_nbobjs_by_type(hwloc.OBJ_CORE)
hwloc旨在跨操作系统和体系结构进行移植。如果您没有Python 2.6,另一个选项是:
import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
在Python 3.4+中:
多处理.cpu_count()
是根据此函数实现的,但如果os,则会引发NotImplementedError
。cpu_count()
返回None
(“无法确定cpu的数量”)。您也可以使用“joblib”实现此目的
import joblib
print joblib.cpu_count()
此方法将为您提供系统中的CPU数量。但是需要安装joblib。更多关于joblib的信息可以在这里找到
或者,您可以使用python的numexpr包。它有许多简单的函数,有助于获取有关系统cpu的信息
import numexpr as ne
print ne.detect_number_of_cores()
如果您想知道物理内核(而不是虚拟超线程内核)的数量,这里有一个独立于平台的解决方案:
psutil.cpu\u计数(逻辑=False)
请注意,逻辑
的默认值为真
,因此,如果要包括超读内核,可以使用:
psutil.cpu\u计数()
这将给出与
os.cpu\u count()
和multiprocessing.cpu\u count()
相同的数字,这两个数字都没有逻辑
关键字参数。这些数字为您提供了超读cpu计数
multiprocessing.cpu\u count()
os.cpu\u count()
psutil.cpu\u count()
numexpr.检测内核的数量()
len(os.sched\u getaffinity(0))
是您通常想要的
os.sched_getaffinity(0)
(在Python 3中添加)返回可用的CPU集,这限制了进程及其子进程可以在哪个CPU上运行
0
表示获取当前进程的值。该函数返回允许的CPU的set()
,因此需要len()
另一方面,
multiprocessing.cpu\u count()
和os.cpu\u count()
只返回物理cpu的总数
这种差异尤其重要,因为某些群集管理系统(如使用sched_getaffinity
限制作业CPU的使用)
因此,如果使用multiprocessing.cpu\u 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(os.cpu_count())
print(len(os.sched_getaffinity(0)))
那么输出是:
16
16
1
Vsnproc
nproc
默认情况下尊重亲缘关系,并且:
taskset -c 0 nproc
产出:
1
而man nproc
则非常明确:
打印可用的处理单元数
因此,默认情况下,len(os.sched_getaffinity(0))
的行为类似于nproc
nproc
具有--all
标志,用于在不考虑任务集的情况下获取物理CPU计数的不太常见的情况:
taskset -c 0 nproc --all
os.cpu\u计数
文档
os.cpu\u count
的文档也简要提到了这一点
此数量不等于当前进程可以使用的CPU数量。可用CPU的数量可以通过len(os.sched_getaffinity(0))
同样的注释也复制在多处理.cpu\u count
的文档中:
从下面的3.8源代码中,我们还可以看到,
多处理.cpu\u计数
仅转发到os.cpu\u计数
,但如果os.cpu\u计数
失败,多处理
将抛出异常而不是返回无异常:
def cpu_count(self):
'''Returns the number of CPUs in the system'''
num = os.cpu_count()
if num is None:
raise NotImplementedError('cannot determine number of cpus')
else:
return num
3.8可用性:具有本机sched_getaffinity
功能的系统
这个os.sched_getaffinity
的唯一缺点是,从Python3.8开始,它似乎只是UNIX
cpython 3.8似乎只是试图编译一个带有sched_setaffinity
fun的小型C hello world
import psutil
print(len(psutil.Process().cpu_affinity()))
import os
workers = os.cpu_count()
if 'sched_getaffinity' in dir(os):
workers = len(os.sched_getaffinity(0))
import torch.multiprocessing as mp
mp.cpu_count()
python -c "import multiprocessing; print(multiprocessing.cpu_count())"