Відповіді:
Якщо у вас python з версією> = 2.6, ви можете просто використовувати
import multiprocessing
multiprocessing.cpu_count()
http://docs.python.org/library/multiprocessing.html#multiprocessing.cpu_count
os.cpu_count()
Якщо вас цікавить кількість процесорів, доступних для вашого поточного процесу, вам слід спочатку перевірити 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')
/proc/self/statusвідповідно є ff, f і f ---, що відповідають 8, 4 і 4 вашою (правильною) математикою. Однак фактична кількість процесорів відповідно 4, 2 і 1. Я вважаю, що підрахунок кількості зустрічей слова "процесор" /proc/cpuinfoможе бути кращим способом. (Або у мене питання неправильне?)
/proc/cpuinfo, якщо для будь-якого з списків кожного "процесора" ви помножите "братів і сестер" на "ядра процесора" ви отримуєте свій номер "Cpus_allowed". І я вважаю, що побратими відносяться до гіперточок, звідси ваше посилання на "віртуальне". Але факт залишається фактом, що у вашому MacPro число "Cpus_allowed" - 8, тоді як ваша multiprocessing.cpu_count()відповідь - 4. Моя власна open('/proc/cpuinfo').read().count('processor')також виробляє 4, кількість фізичних ядер (два двоядерні процесори).
open('/proc/self/status').read()забуває закрити файл. Використовуйте with open('/proc/self/status') as f: f.read()замість цього
os.cpu_count()
withколи ви стикаєтеся з випадком, коли це вам потрібно.
Іншим варіантом є використання psutilбібліотеки, яка завжди виявляється корисною в таких ситуаціях:
>>> import psutil
>>> psutil.cpu_count()
2
Це має працювати на будь-якій платформі, підтримуваній psutil (Unix та Windows).
Зауважте, що в деяких випадках multiprocessing.cpu_countможе збільшитись NotImplementedErrorчас psutil, зможете отримати кількість процесорів. Це просто тому, що psutilспочатку намагаються використовувати ті самі методи, якими вони користуються, multiprocessingа якщо вони не вдаються, вони також використовують інші методи.
psutil.cpu_count(logical = True)
psutil.cpu_count()дає 12 (це 6-ядерний процесор з гіперточенням). Це тому, що аргумент за замовчуванням logical- True, тому вам явно потрібно написати, psutil.cpu_count(logical = False)щоб отримати кількість фізичних ядер.
У Python 3.4+ : os.cpu_count () .
multiprocessing.cpu_count()реалізується з точки зору цієї функції, але збільшується, NotImplementedErrorякщо os.cpu_count()повертається None("не вдається визначити кількість процесорів").
cpu_count. len(os.sched_getaffinity(0))може бути краще, залежно від мети.
os.cpu_count()що запитує ОП) може відрізнятися від кількості ЦП, доступних для поточного процесу ( os.sched_getaffinity(0)).
os.sched_getaffinity(0)це НЕ є на BSD, тому використання os.cpu_count()не потрібно (без інших зовнішніх бібліотек, тобто).
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, обмежують використання CPU у роботі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 спорідненості, можливо SetProcessAffinityMask, тому мені цікаво, чому він не був перенесений. Але я нічого не знаю про Windows.
Тестовано в Ubuntu 16.04, Python 3.5.2.
платформа незалежна:
psutil.cpu_count (логічно = помилково)
psutil.cpu_count(logical=False) #4 psutil.cpu_count(logical=True) #8таmultiprocessing.cpu_count() #8
Вони дають вам підрахунок процесора
multiprocessing.cpu_count()os.cpu_count()Вони дають вам кількість процесорів віртуальної машини
psutil.cpu_count()numexpr.detect_number_of_cores()Має значення лише те, якщо ви працюєте на віртуальних машинах.
os.cpu_count()і multiprocessing.cpu_count()повертаються гіпертрезовані підрахунки процесора, а не фактичні фізичні підрахунки процесора.
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 розроблений так, щоб він був портативним в ОС та архітектурах.
psutil.cpu_count(logical=False)
Неможливо зрозуміти, як додати до коду чи відповісти на повідомлення, але ось підтримка 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()
Цей метод дасть вам кількість cpus в системі. joblib потрібно встановити. Більше інформації про joblib можна знайти тут https://pythonhosted.org/joblib/parallel.html
Крім того, ви можете використовувати numexpr пакет python. У ньому багато простих функцій, корисних для отримання інформації про системний процесор.
import numexpr as ne
print ne.detect_number_of_cores()
Ще один варіант, якщо у вас немає Python 2.6:
import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
/proc/<PID>/statusмістить рядки, які повідомляють вам кількість процесорів у поточному процесорі: шукайтеCpus_allowed_list.