Antworten:
Wenn Sie Python mit einer Version> = 2.6 haben, können Sie einfach verwenden
import multiprocessing
multiprocessing.cpu_count()
http://docs.python.org/library/multiprocessing.html#multiprocessing.cpu_count
os.cpu_count()
Wenn Sie an der Anzahl der Prozessoren interessiert sind, die für Ihren aktuellen Prozess verfügbar sind, müssen Sie zuerst cpuset überprüfen . Andernfalls (oder wenn cpuset nicht verwendet wird) multiprocessing.cpu_count()
ist dies der richtige Weg in Python 2.6 und höher. Die folgende Methode greift auf einige alternative Methoden in älteren Versionen von Python zurück:
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 und f --- entsprechend 8, 4 und 4 nach Ihrer (richtigen) Mathematik. Die tatsächliche Anzahl der CPUs beträgt jedoch 4, 2 und 1. Ich finde, dass das Zählen der Anzahl der Vorkommen des Wortes "Prozessor" /proc/cpuinfo
der bessere Weg sein kann. (Oder habe ich die Frage falsch?)
/proc/cpuinfo
, wenn Sie für eine der Auflistungen für jeden "Prozessor" die "Geschwister" mit den "CPU-Kernen" multiplizieren. Sie erhalten Ihre "Cpus_allowed" Nummer. Und ich stelle fest, dass sich die Geschwister auf Hyper-Threading beziehen, daher Ihr Hinweis auf "virtuell". Es bleibt jedoch die Tatsache, dass Ihre "Cpus_allowed" -Nummer auf meinem MacPro 8 ist, während Ihre multiprocessing.cpu_count()
Antwort 4 ist. Meine eigene open('/proc/cpuinfo').read().count('processor')
erzeugt auch 4, die Anzahl der physischen Kerne (zwei Dual-Core-Prozessoren).
open('/proc/self/status').read()
vergisst, die Datei zu schließen. Verwenden Sie with open('/proc/self/status') as f: f.read()
stattdessen
os.cpu_count()
with
wenn Sie auf einen Fall stoßen, in dem Sie ihn brauchen.
Eine andere Möglichkeit ist die Verwendung der psutil
Bibliothek, die sich in folgenden Situationen immer als nützlich erweist:
>>> import psutil
>>> psutil.cpu_count()
2
Dies sollte auf jeder von psutil
(Unix und Windows) unterstützten Plattform funktionieren .
Beachten Sie, dass in einigen Fällen multiprocessing.cpu_count
eine NotImplementedError
Weile psutil
dauern kann, um die Anzahl der CPUs zu ermitteln. Dies liegt einfach daran, dass psutil
zuerst versucht wird, dieselben Techniken zu verwenden, die von verwendet werden, multiprocessing
und wenn diese fehlschlagen, werden auch andere Techniken verwendet.
psutil.cpu_count(logical = True)
psutil.cpu_count()
gibt es 12 (es ist eine 6-Kern-CPU mit Hyperthreading). Dies liegt daran, dass das Standardargument von logical
True ist. Sie müssen also explizit schreiben psutil.cpu_count(logical = False)
, um die Anzahl der physischen Kerne zu ermitteln.
In Python 3.4+: os.cpu_count () .
multiprocessing.cpu_count()
wird in Bezug auf diese Funktion implementiert, wird jedoch ausgelöst, NotImplementedError
wenn os.cpu_count()
zurückgegeben wird None
("Anzahl der CPUs kann nicht bestimmt werden").
cpu_count
. len(os.sched_getaffinity(0))
könnte je nach Zweck besser sein.
os.cpu_count()
was OP fragt) kann von der Anzahl der CPUs abweichen, die für den aktuellen Prozess verfügbar sind ( os.sched_getaffinity(0)
).
os.sched_getaffinity(0)
ist auf BSD nicht verfügbar, daher ist die Verwendung von os.cpu_count()
erforderlich (dh ohne andere externe Bibliothek).
len(os.sched_getaffinity(0))
ist das, was du normalerweise willst
https://docs.python.org/3/library/os.html#os.sched_getaffinity
os.sched_getaffinity(0)
(in Python 3 hinzugefügt) gibt die verfügbaren CPUs unter Berücksichtigung des sched_setaffinity
Linux-Systemaufrufs zurück , wodurch begrenzt wird, auf welchen CPUs ein Prozess und seine untergeordneten Komponenten ausgeführt werden können.
0
bedeutet, den Wert für den aktuellen Prozess zu erhalten. Die Funktion gibt eine set()
der zulässigen CPUs zurück, daher ist dies erforderlich len()
.
multiprocessing.cpu_count()
Auf der anderen Seite wird nur die Gesamtzahl der physischen CPUs zurückgegeben.
Der Unterschied ist besonders wichtig, da bestimmte Cluster-Management-Systeme wie Platform LSF die CPU-Auslastung von Jobs einschränken sched_getaffinity
.
Wenn Sie also verwenden multiprocessing.cpu_count()
, versucht Ihr Skript möglicherweise, weit mehr Kerne als verfügbar zu verwenden, was zu Überlastung und Zeitüberschreitungen führen kann.
Wir können den Unterschied konkret erkennen, indem wir die Affinität zum taskset
Nutzen einschränken .
Wenn ich beispielsweise Python in meinem 16-Kern-System auf nur 1 Kern (Kern 0) beschränke:
taskset -c 0 ./main.py
mit dem Testskript:
main.py.
#!/usr/bin/env python3
import multiprocessing
import os
print(multiprocessing.cpu_count())
print(len(os.sched_getaffinity(0)))
dann ist die Ausgabe:
16
1
nproc
respektiert jedoch standardmäßig die Affinität und:
taskset -c 0 nproc
Ausgänge:
1
und man nproc
macht das ganz deutlich:
Drucken Sie die Anzahl der verfügbaren Verarbeitungseinheiten
nproc
hat das --all
Flag für den selteneren Fall, dass Sie die physische CPU-Anzahl erhalten möchten:
taskset -c 0 nproc --all
Der einzige Nachteil dieser Methode ist, dass dies anscheinend nur UNIX ist. Ich nahm an, dass Windows möglicherweise eine ähnliche Affinitäts-API haben muss SetProcessAffinityMask
, also frage ich mich, warum es nicht portiert wurde. Aber ich weiß nichts über Windows.
Getestet in Ubuntu 16.04, Python 3.5.2.
Plattformunabhängig:
psutil.cpu_count (logisch = falsch)
psutil.cpu_count(logical=False) #4
psutil.cpu_count(logical=True) #8
undmultiprocessing.cpu_count() #8
Diese geben Ihnen die Hyperthread-CPU-Anzahl
multiprocessing.cpu_count()
os.cpu_count()
Diese geben Ihnen die CPU-Anzahl der virtuellen Maschine
psutil.cpu_count()
numexpr.detect_number_of_cores()
Nur wichtig, wenn Sie auf VMs arbeiten.
os.cpu_count()
und multiprocessing.cpu_count()
wird mit Hyper - Threading - CPU zählt zurückkehren, nicht die tatsächliche physische CPU - Anzahl.
multiprocessing.cpu_count()
Gibt die Anzahl der logischen CPUs zurück. Wenn Sie also eine Quad-Core-CPU mit Hyperthreading haben, wird diese zurückgegeben 8
. Wenn Sie die Anzahl der physischen CPUs angeben möchten, verwenden Sie die Python-Bindungen für hwloc:
#!/usr/bin/env python
import hwloc
topology = hwloc.Topology()
topology.load()
print topology.get_nbobjs_by_type(hwloc.OBJ_CORE)
hwloc ist für Betriebssysteme und Architekturen portierbar.
psutil.cpu_count(logical=False)
Ich kann nicht herausfinden, wie ich dem Code etwas hinzufügen oder auf die Nachricht antworten kann, aber hier ist die Unterstützung für Jython, die Sie einfügen können, bevor Sie aufgeben:
# jython
try:
from java.lang import Runtime
runtime = Runtime.getRuntime()
res = runtime.availableProcessors()
if res > 0:
return res
except ImportError:
pass
Sie können zu diesem Zweck auch "joblib" verwenden.
import joblib
print joblib.cpu_count()
Diese Methode gibt Ihnen die Anzahl der CPUs im System. joblib muss allerdings installiert sein. Weitere Informationen zu joblib finden Sie hier https://pythonhosted.org/joblib/parallel.html
Alternativ können Sie das Python-Paket numexpr verwenden. Es hat viele einfache Funktionen, die hilfreich sind, um Informationen über die System-CPU zu erhalten.
import numexpr as ne
print ne.detect_number_of_cores()
Eine weitere Option, wenn Sie nicht über Python 2.6 verfügen:
import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
/proc/<PID>/status
hat einige Zeilen, die Ihnen die Anzahl der CPUs im aktuellen cpuset mitteilen: suchen Sie nachCpus_allowed_list
.