Я хочу знать количество процессоров на локальной машине с помощью Python. Результат должен быть user/real
в качестве вывода time(1)
при вызове с оптимальным масштабированием программы только для пользовательского пространства.
Как узнать количество процессоров, использующих python
Ответ 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'^[email protected][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
, которая всегда psutil
полезной в следующих ситуациях:
>>> import psutil
>>> psutil.cpu_count()
2
Это должно работать на любой платформе, поддерживаемой psutil
(Unix и Windows).
Обратите внимание, что в некоторых случаях multiprocessing.cpu_count
может вызвать NotImplementedError
тогда как psutil
сможет получить количество процессоров. Это просто потому, что psutil
сначала пытается использовать те же методы, что и multiprocessing
и, если они не psutil
, он также использует другие методы.
Ответ 4
В Python 3.4+: os.cpu_count().
multiprocessing.cpu_count()
реализуется с точки зрения этой функции, но вызывает NotImplementedError
, если os.cpu_count()
возвращает None
( "не может определить количество процессоров" ).
Ответ 5
import os
print(os.cpu_count())
Ответ 6
независимая платформа:
psutil.cpu_count (логическое = False)
Ответ 7
multiprocessing.cpu_count()
вернет количество логических процессоров, поэтому, если у вас есть четырехъядерный процессор с гиперпотоком, он вернет 8
. Если вы хотите количество физических процессоров, используйте привязки python для hwloc:
#!/usr/bin/env python
import hwloc
topology = hwloc.Topology()
topology.load()
print topology.get_nbobjs_by_type(hwloc.OBJ_CORE)
hwloc предназначен для переносимости по всем операционным системам и архитектурам.
Ответ 8
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, который ограничивает, на каких процессорах процесс и его дочерние элементы могут работать.
0
означает получить значение для текущего процесса. Функция возвращает set()
разрешенных процессоров, таким образом, необходимость в len()
.
multiprocessing.cpu_count()
с другой стороны, просто возвращает общее количество физических процессоров.
Разница особенно важна, потому что некоторые системы управления кластером, такие как платформа LSF, ограничивают использование ЦП заданием с sched_getaffinity
.
Поэтому, если вы используете multiprocessing.cpu_count()
, ваш скрипт может попытаться использовать больше ядер, чем у него есть, что может привести к перегрузке и тайм-аутам.
Мы можем увидеть разницу конкретно, ограничив сродство утилитой taskset
.
Например, если я ограничу Python только одним ядром (ядро 0) в моей 16-ядерной системе:
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
для менее распространенного случая, когда вы хотите получить физический счетчик ЦП:
taskset -c 0 nproc --all
Единственным недостатком этого метода является то, что это только UNIX. Я предположил, что в Windows должен быть похожий API-интерфейс, возможно SetProcessAffinityMask
, поэтому мне интересно, почему он не был портирован. Но я ничего не знаю о Windows.
Протестировано в Ubuntu 16.04, Python 3.5.2.
Ответ 9
Невозможно выяснить, как добавить код или ответить на сообщение, но вот поддержка jython, с которой вы можете столкнуться, прежде чем отказаться:
# jython
try:
from java.lang import Runtime
runtime = Runtime.getRuntime()
res = runtime.availableProcessors()
if res > 0:
return res
except ImportError:
pass
Ответ 10
Для этой цели вы также можете использовать "joblib".
import joblib
print joblib.cpu_count()
Этот метод даст вам количество процессоров в системе. joblib должен быть установлен. Более подробную информацию о joblib можно найти здесь https://pythonhosted.org/joblib/parallel.html
В качестве альтернативы вы можете использовать пакет numexpr для python. Он имеет множество простых функций, полезных для получения информации о системном процессоре.
import numexpr as ne
print ne.detect_number_of_cores()
Ответ 11
Они дают вам подсчитанное количество процессоров
-
multiprocessing.cpu_count()
-
os.cpu_count()
Они дают вам количество процессоров виртуальной машины
-
psutil.cpu_count()
-
numexpr.detect_number_of_cores()
Имеет значение только если вы работаете на виртуальных машинах.
Ответ 12
Другой вариант, если у вас нет Python 2.6:
import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
Ответ 13
Это функция 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')