我想用Python知道本地机器上cpu的数量。当使用一个优化伸缩的仅用户空间的程序调用时,结果应该是user/real作为时间(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.6的python,你可以简单地使用
import multiprocessing
multiprocessing.cpu_count()
http://docs.python.org/library/multiprocessing.html#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
另一种选择是使用psutil库,它在这些情况下总是很有用:
>>> import psutil
>>> psutil.cpu_count()
2
这应该可以在psutil支持的任何平台上工作(Unix和Windows)。
注意在某些情况下多处理。cpu_count可能引发NotImplementedError,而psutil将能够获得cpu的数量。这只是因为psutil首先尝试使用多处理所使用的相同技术,如果这些技术失败,它还会使用其他技术。
multiprocessing.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+: os.cpu_count()。
multiprocessing.cpu_count()是根据这个函数实现的,但如果os.cpu_count()返回None(“不能确定cpu数量”)则会引发NotImplementedError。
你也可以使用“joblib”来达到这个目的。
import joblib
print joblib.cpu_count()
此方法将为您提供系统中的cpu数量。但是Joblib需要安装。更多关于joblib的信息可以在这里找到https://pythonhosted.org/joblib/parallel.html
或者,您可以使用python的numexpr包。它有很多简单的功能,有助于获取关于系统cpu的信息。
import numexpr as ne
print ne.detect_number_of_cores()
如果你想知道物理内核的数量(不是虚拟超线程内核),这里有一个独立于平台的解决方案:
psutil.cpu_count(logical=False)
https://github.com/giampaolo/psutil/blob/master/INSTALL.rst
注意,logical的默认值是True,所以如果你想包含超线程核心,你可以使用:
psutil.cpu_count()
这将给出与os.cpu_count()和multiprocessing.cpu_count()相同的数字,这两个都没有逻辑关键字参数。
这将提供超线程CPU计数
multiprocessing.cpu_count () os.cpu_count ()
这些参数提供了虚拟机CPU计数
psutil.cpu_count () numexpr.detect_number_of_cores ()
只有在虚拟机上工作时才重要。
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系统调用的可用cpu集,该调用限制了进程及其子进程可以在哪些cpu上运行。
0表示获取当前进程的值。该函数返回一组允许使用的cpu(),因此需要使用len()。
另一方面,multiprocessing.cpu_count()和os.cpu_count()只返回物理cpu的总数。
这种差异尤其重要,因为某些集群管理系统(如Platform LSF)使用sched_getaffinity限制作业CPU的使用。
因此,如果您使用multiprocessing.cpu_count(),您的脚本可能会尝试使用比可用内核更多的内核,这可能会导致过载和超时。
通过限制与任务集实用程序的亲和性,我们可以看到具体的区别,它允许我们控制进程的亲和性。
最小任务集示例
例如,如果在我的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
Vs nproc
Nproc默认情况下尊重亲缘性,并且:
taskset -c 0 nproc
输出:
1
man nproc把这一点说得很清楚:
打印可用的处理单元数量
因此,len(os.sched_getaffinity(0))在默认情况下的行为类似于nproc。
nproc有——all标志,在不太常见的情况下,你想要获得物理CPU计数而不考虑任务集:
taskset -c 0 nproc --all
操作系统。cpu_count文档
操作系统文档。Cpu_count还简要地提到了这个https://docs.python.org/3.8/library/os.html#os.cpu_count
这个数字并不等同于当前进程可以使用的cpu数量。可用cpu的数量可以通过len(os.sched_getaffinity(0))获得。
同样的注释也复制到multiprocessing的文档中。cpu_count: https://docs.python.org/3/library/multiprocessing.html # multiprocessing.cpu_count
在Lib/multiprocessing/context.py下的3.8源代码中,我们也看到了multiprocessing. py。Cpu_count只是转发给os。cpu_count,只是如果os. cpu_count是多处理的,则会抛出异常而不是返回None。cpu_count失败:
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函数的系统
这个操作系统唯一的缺点。sched_getaffinity是在Python 3.8之后才出现的。
cpython 3.8似乎只是试图在配置时使用sched_setaffinity函数调用编译一个小型C hello世界,如果没有出现HAVE_SCHED_SETAFFINITY,则该函数可能会丢失:
https://github.com/python/cpython/blob/v3.8.5/configure#L11523 https://github.com/python/cpython/blob/v3.8.5/Modules/posixmodule.c#L6457
psutil.Process().cpu_affinity(): Windows端口号的第三方版本
第三方psutil包(pip install psutil)已在https://stackoverflow.com/a/14840102/895245上提到,但没有提到cpu_affinity函数:https://psutil.readthedocs.io/en/latest/#psutil.Process.cpu_affinity
用法:
import psutil
print(len(psutil.Process().cpu_affinity()))
这个函数的作用与标准库os。在Linux上的sched_getaffinitymask,但是他们也在Windows上实现了它,通过调用GetProcessAffinityMask Windows API函数:
https://github.com/giampaolo/psutil/blob/ee60bad610822a7f630c52922b4918e684ba7695/psutil/_psutil_windows.c#L1112 https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getprocessaffinitymask
换句话说:那些Windows用户必须停止懒惰,并发送一个补丁到上游的stdlib:-)
在Ubuntu 16.04, Python 3.5.2中测试。
这可能适用于我们这些使用不同操作系统的人,但想要获得所有世界的最好:
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()
torch中的mp库具有与python主库相同的接口,所以你也可以这样做,正如评论者所提到的:
python -c "import multiprocessing; print(multiprocessing.cpu_count())"
希望这能有所帮助!;)有多个选择总是好的。
对于python 3.4以上版本,可以使用
import os
os.cpu_count()
如果你正在寻找linux命令nproc的等价物。你有这个选项
len(os.sched_getaffinity(0))
如果您正在寻找打印系统中的核数。
试试这个:
import os
no_of_cores = os.cpu_count()
print(no_of_cores)
这应该会有所帮助。
推荐文章
- 将Pandas或Numpy Nan替换为None以用于MysqlDB
- 使用pandas对同一列进行多个聚合
- 使用Python解析HTML
- django MultiValueDictKeyError错误,我如何处理它
- 如何在for循环期间修改列表条目?
- 我如何在Django中创建一个鼻涕虫?
- 没有名为'django.core.urlresolvers'的模块
- 蟒蛇导出环境文件
- Django - makemigrations -未检测到任何更改
- SQLAlchemy:引擎、连接和会话差异
- 在Python Pandas中删除多个列中的所有重复行
- 更改pandas DataFrame中的特定列名
- 将Pandas多索引转换为列
- 熊猫在每组中获得最高的n个记录
- 熊猫数据帧得到每组的第一行