Как узнать количество процессоров с помощью python
-
06-07-2019 - |
Вопрос
Я хочу знать количество процессоров на локальном компьютере, используя Python.Результатом должно быть user/real
как результат с помощью time(1)
при вызове с помощью программы, оптимально масштабируемой только для пользовательского пространства.
Решение 2
Если вас интересует число процессоров, доступных для вашего текущего процесса, вы должны проверить 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')
Другие советы
Если у вас есть python с версией > = 2.6, вы можете просто использовать
import multiprocessing
multiprocessing.cpu_count()
http://docs.python.org/library/multiprocessing.html# multiprocessing.cpu_count р>
Другой вариант - использовать библиотеку psutil
, которая всегда получается полезно в таких ситуациях:
>>> import psutil
>>> psutil.cpu_count()
2
Это должно работать на любой платформе, поддерживаемой psutil
(Unix и Windows).
Обратите внимание, что в некоторых случаях multiprocessing.cpu_count
может вызвать NotImplementedError
, тогда как psutil
сможет получить количество процессоров. Это просто потому, что psutil
сначала пытается использовать те же методы, которые использовались в multiprocessing
, и, если они терпят неудачу, он также использует другие методы.
В Python 3.4+: os.cpu_count () .
multiprocessing.cpu_count ()
реализован в терминах этой функции, но вызывает NotImplementedError
, если os.cpu_count ()
возвращает None
(" не могу определить количество процессоров ").
import os
print(os.cpu_count())
независимый от платформы:
psutil.cpu_count(логическое значение=False)
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 предназначен для переноса между операционными системами и архитектурами.
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 только 1 ядром (core 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 affinity, возможно SetProcessAffinityMask
, поэтому я удивляюсь, почему он не был портирован.Но я ничего не знаю о Windows.
Протестировано в Ubuntu 16.04, Python 3.5.2.
Не могу понять, как добавить код или ответить на сообщение, но вот поддержка jython, которую вы можете использовать перед тем, как сдаться:
# jython
try:
from java.lang import Runtime
runtime = Runtime.getRuntime()
res = runtime.availableProcessors()
if res > 0:
return res
except ImportError:
pass
Вы также можете использовать " joblib " для этого. Р>
import joblib
print joblib.cpu_count()
Этот метод даст вам количество процессоров в системе. joblib должен быть установлен, хотя. Дополнительную информацию о joblib можно найти здесь https://pythonhosted.org/joblib/parallel.html . р>
В качестве альтернативы вы можете использовать Numberxpr пакет Python. В нем много простых функций, полезных для получения информации о системном процессоре.
import numexpr as ne
print ne.detect_number_of_cores()
Они дают вам подсчет сверхпоточных процессоров
<Ол> <Литий> <код> multiprocessing.cpu_count () код> литий> <Литий> <код> os.cpu_count () код> литий> Ол>Они дают вам количество ЦП виртуальной машины
<Ол> <Литий> <код> psutil.cpu_count () код> литий>Имеет значение только если вы работаете на виртуальных машинах.
Другой вариант, если у вас нет Python 2.6:
import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")