Wie man die Anzahl der CPUs mit Python herauszufinden,
-
06-07-2019 - |
Frage
Ich mag die Anzahl der CPUs auf dem lokalen Rechner wissen, mit Python. Das Ergebnis sollte als Ausgabe von user/real
time(1)
werden, wenn sie mit einem optimal Skalierung User-Space-only-Programm genannt.
Lösung 2
Wenn Sie sich in der Anzahl der Prozessoren sind verfügbar Ihren aktuellen Prozess, müssen Sie prüfen, cpuset zuerst. Andernfalls (oder wenn CPU-Satz nicht in Gebrauch ist), multiprocessing.cpu_count()
ist der Weg in Python 2.6 und höher zu gehen. Die folgende Methode fällt zurück auf ein paar alternativen Methoden in älteren Versionen von 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')
Andere Tipps
Wenn Sie Python mit einer Version haben> = 2.6 können Sie einfach verwenden
import multiprocessing
multiprocessing.cpu_count()
http://docs.python.org/library/multiprocessing.html# multiprocessing.cpu_count
Eine weitere Option ist die psutil
Bibliothek zu verwenden, die nützlich in diesen Situationen herausstellen:
>>> import psutil
>>> psutil.cpu_count()
2
Dies sollte durch psutil
(Unix und Windows), die auf jeder Plattform arbeiten.
Beachten Sie, dass in einigen Fällen multiprocessing.cpu_count
eine NotImplementedError
erhöhen können, während psutil
Lage sein wird, die Anzahl der CPUs zu erhalten. Das ist einfach weil psutil
zuerst versucht, die gleichen Techniken, die von multiprocessing
verwendet zu verwenden und, wenn diese versagen, es nutzt auch andere Techniken.
In Python 3.4+. os.cpu_count ()
multiprocessing.cpu_count()
im Sinne dieser Funktion implementiert ist, sondern wirft NotImplementedError
wenn os.cpu_count()
kehrt None
( „kann nicht Anzahl der CPUs bestimmen“).
import os
print(os.cpu_count())
plattformunabhängig:
psutil.cpu_count (logisch = False)
multiprocessing.cpu_count()
wird die Anzahl der logischen CPUs zurückkehren, wenn Sie also einen Quad-Core-CPU mit Hyperthreading haben, wird es zurückkehren 8
. Wenn Sie die Anzahl der physischen CPUs wollen, verwenden Sie die Python-Anbindung an hwloc:
#!/usr/bin/env python
import hwloc
topology = hwloc.Topology()
topology.load()
print topology.get_nbobjs_by_type(hwloc.OBJ_CORE)
hwloc ist so konzipiert, tragbarer über OSes und Architekturen sein.
len(os.sched_getaffinity(0))
ist, was Sie wollen in der Regel
https://docs.python.org/3/library /os.html#os.sched_getaffinity
os.sched_getaffinity(0)
(hinzugefügt in Python 3) gibt die Menge der verfügbaren CPUs in Anbetracht der sched_setaffinity
Linux-Systemaufruf , die Grenzen, die einen Prozess-CPUs und ihre Kinder können laufen.
0
ist der Wert für den aktuellen Prozess zu bekommen. Die Funktion gibt einen set()
des erlaubten CPUs, wodurch die Notwendigkeit für len()
.
multiprocessing.cpu_count()
auf der anderen Seite gibt nur die Gesamtzahl der physischen CPUs.
Der Unterschied ist besonders wichtig, weil bestimmte Cluster-Management-Systeme wie zum Beispiel Platform LSF Limit Job CPU Verwendung mit sched_getaffinity
.
Wenn Sie also multiprocessing.cpu_count()
verwenden, Ihr Skript könnte versuchen, viel mehr Kerne zu verwenden, als es zur Verfügung hat, die zu Überlastung und Timeouts führen kann.
Wir können den Unterschied sehen konkret durch die Affinität mit dem taskset
Dienstprogramm zu beschränken.
Zum Beispiel, wenn ich beschränken Python nur 1 Kern (Kern 0) in meinem 16-Core-System:
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 der Ausgang:
16
1
nproc
Hinsicht Affinität von Standard:
taskset -c 0 nproc
Ausgänge:
1
und man nproc
macht das ganz deutlich:
drucken Sie die Anzahl der Verarbeitungseinheiten verfügbar
nproc
hat den --all
Flag für den selteneren Fall, dass Sie die physische CPU-Anzahl erhalten mögen:
taskset -c 0 nproc --all
Der einzige Nachteil dieser Methode ist, dass dies nur UNIX zu sein scheint. Ich soll Windows-API eine ähnliche Affinität haben muss, möglicherweise SetProcessAffinityMask
, so frage ich mich, warum es nicht portiert. Aber ich weiß nichts über Windows.
Getestet in Ubuntu 16.04, Python 3.5.2.
Kann nicht herausfinden, wie man den Code hinzuzufügen, oder auf die Nachricht antworten, aber hier ist die Unterstützung für jython, die Sie tack in 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 auch „JOBLIB“ für diesen Zweck verwenden.
import joblib
print joblib.cpu_count()
Mit dieser Methode geben Sie die Anzahl der CPUs im System. JOBLIB muss allerdings installiert werden. Mehr Informationen über JOBLIB Hier finden Sie https://pythonhosted.org/joblib/parallel.html
Alternativ können Sie Paket von Python verwenden numexpr. Es hat viele einfache Funktionen hilfreich, um Informationen über den System-CPU zu bekommen.
import numexpr as ne
print ne.detect_number_of_cores()
Diese geben Ihnen die Hyper-Threading-CPU-Anzahl
-
multiprocessing.cpu_count()
-
os.cpu_count()
Diese geben Sie die virtuelle Maschine CPU-Anzahl
-
psutil.cpu_count()
-
numexpr.detect_number_of_cores()
Nur Angelegenheiten, wenn Sie auf VMs funktioniert.
Eine weitere Option, wenn Sie nicht über Python 2.6:
import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")