我想知道使用Python的本地机器上的CPU数量。当使用最佳扩展用户空间程序调用时,结果应为user/real
time(1)
的输出。
答案 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)
答案 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)
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计数
这些为您提供虚拟机的CPU计数
只有在虚拟机上工作才重要。
答案 15 :(得分:1)
这可能适合那些使用不同操作系统/系统,但又想获得世界最佳水平的人:
import os
workers = os.cpu_count()
if 'sched_getaffinity' in dir(os):
workers = len(os.sched_getaffinity(0))