Réponses:
Si vous avez python avec une version> = 2.6, vous pouvez simplement utiliser
import multiprocessing
multiprocessing.cpu_count()
http://docs.python.org/library/multiprocessing.html#multiprocessing.cpu_count
os.cpu_count()
Si vous êtes intéressé par le nombre de processeurs disponibles pour votre processus actuel, vous devez d'abord vérifier cpuset . Sinon (ou si cpuset n'est pas utilisé), multiprocessing.cpu_count()
c'est la voie à suivre en Python 2.6 et plus récent. La méthode suivante revient à quelques méthodes alternatives dans les anciennes versions de 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
sont respectivement ff, f et f --- correspondant à 8, 4 et 4 par votre (correct) calcul. Cependant, le nombre réel de CPU est respectivement de 4, 2 et 1. Je trouve que compter le nombre d'occurrences du mot "processeur" /proc/cpuinfo
peut être la meilleure façon de procéder. (Ou ai-je une mauvaise question?)
/proc/cpuinfo
cela si pour l'une des listes de chaque "processeur" vous multipliez les "frères et sœurs" par les "cœurs de processeur" vous obtenez votre numéro "Cpus_allowed". Et je suppose que les frères et sœurs se réfèrent à l'hyper-threading, d'où votre référence au "virtuel". Mais le fait demeure que votre numéro "Cpus_allowed" est 8 sur mon MacPro alors que votre multiprocessing.cpu_count()
réponse est 4. Le mien open('/proc/cpuinfo').read().count('processor')
produit également 4, le nombre de cœurs physiques (deux processeurs dual-core).
open('/proc/self/status').read()
oublie de fermer le fichier. Utilisez with open('/proc/self/status') as f: f.read()
plutôt
os.cpu_count()
with
lorsque vous rencontrez un cas où vous en avez besoin.
Une autre option consiste à utiliser la psutil
bibliothèque, qui s'avère toujours utile dans ces situations:
>>> import psutil
>>> psutil.cpu_count()
2
Cela devrait fonctionner sur n'importe quelle plate-forme prise en charge par psutil
(Unix et Windows).
Notez que, dans certaines occasions, multiprocessing.cpu_count
peut soulever un NotImplementedError
certain temps psutil
sera en mesure d'obtenir le nombre de processeurs. C'est tout simplement parce que psutil
tente d'abord d'utiliser les mêmes techniques utilisées par multiprocessing
et, si celles-ci échouent, il utilise également d'autres techniques.
psutil.cpu_count(logical = True)
psutil.cpu_count()
donne 12 (c'est un processeur 6 cœurs avec hyperthreading). En effet, l'argument par défaut de logical
est True, vous devez donc explicitement écrire psutil.cpu_count(logical = False)
pour obtenir le nombre de cœurs physiques.
En Python 3.4+: os.cpu_count () .
multiprocessing.cpu_count()
est implémenté en termes de cette fonction mais augmente NotImplementedError
si os.cpu_count()
renvoie None
("ne peut pas déterminer le nombre de CPU").
cpu_count
. len(os.sched_getaffinity(0))
pourrait être mieux, selon le but.
os.cpu_count()
ce que demande OP) peut différer du nombre de CPU disponibles pour le processus en cours ( os.sched_getaffinity(0)
).
os.sched_getaffinity(0)
n'est pas disponible sur BSD, donc l'utilisation de os.cpu_count()
est requise (sans autre bibliothèque externe, c'est-à-dire).
len(os.sched_getaffinity(0))
c'est ce que tu veux d'habitude
https://docs.python.org/3/library/os.html#os.sched_getaffinity
os.sched_getaffinity(0)
(ajouté dans Python 3) renvoie l'ensemble des processeurs disponibles compte tenu de l' sched_setaffinity
appel système Linux , ce qui limite les processeurs sur lesquels un processus et ses enfants peuvent s'exécuter.
0
signifie obtenir la valeur du processus en cours. La fonction renvoie un set()
des CPU autorisés, d'où la nécessité len()
.
multiprocessing.cpu_count()
d'autre part, renvoie simplement le nombre total de CPU physiques.
La différence est particulièrement importante car certains systèmes de gestion de cluster tels que Platform LSF limitent l'utilisation du processeur de travail avec sched_getaffinity
.
Par conséquent, si vous utilisez multiprocessing.cpu_count()
, votre script peut essayer d'utiliser beaucoup plus de cœurs qu'il n'en a, ce qui peut entraîner une surcharge et des délais d'attente.
On peut voir la différence concrètement en restreignant l'affinité avec l' taskset
utilité.
Par exemple, si je limite Python à seulement 1 cœur (cœur 0) dans mon système à 16 cœurs:
taskset -c 0 ./main.py
avec le script de test:
main.py
#!/usr/bin/env python3
import multiprocessing
import os
print(multiprocessing.cpu_count())
print(len(os.sched_getaffinity(0)))
alors la sortie est:
16
1
nproc
respecte cependant l'affinité par défaut et:
taskset -c 0 nproc
les sorties:
1
et man nproc
rend cela assez explicite:
imprimer le nombre d'unités de traitement disponibles
nproc
a l' --all
indicateur pour le cas le moins courant où vous souhaitez obtenir le nombre d'UC physiques:
taskset -c 0 nproc --all
Le seul inconvénient de cette méthode est qu'elle semble être uniquement UNIX. Je supposais que Windows devait avoir une API d'affinité similaire SetProcessAffinityMask
, donc je me demande pourquoi il n'a pas été porté. Mais je ne connais rien de Windows.
Testé dans Ubuntu 16.04, Python 3.5.2.
Si vous souhaitez connaître le nombre de cœurs physiques (pas les cœurs virtuels hyperthreadés), voici une solution indépendante de la plateforme:
psutil.cpu_count(logical=False)
https://github.com/giampaolo/psutil/blob/master/INSTALL.rst
Notez que la valeur par défaut de logical
est True
, donc si vous souhaitez inclure des cœurs hyperthreadés, vous pouvez utiliser:
psutil.cpu_count()
Cela donnera le même nombre que os.cpu_count()
et multiprocessing.cpu_count()
, dont aucun n'a l' logical
argument mot - clé.
psutil.cpu_count(logical=False) #4
psutil.cpu_count(logical=True) #8
etmultiprocessing.cpu_count() #8
Cela vous donne le nombre de CPU hyperthreaded
multiprocessing.cpu_count()
os.cpu_count()
Cela vous donne le nombre de CPU de la machine virtuelle
psutil.cpu_count()
numexpr.detect_number_of_cores()
N'importe que si vous travaillez sur des machines virtuelles.
os.cpu_count()
et multiprocessing.cpu_count()
renverra le nombre de processeurs hyperthreadés, et non le nombre réel de processeurs physiques.
multiprocessing.cpu_count()
renverra le nombre de CPU logiques, donc si vous avez un CPU quad-core avec hyperthreading, il reviendra 8
. Si vous voulez le nombre de CPU physiques, utilisez les liaisons python pour hwloc:
#!/usr/bin/env python
import hwloc
topology = hwloc.Topology()
topology.load()
print topology.get_nbobjs_by_type(hwloc.OBJ_CORE)
hwloc est conçu pour être portable sur différents OS et architectures.
psutil.cpu_count(logical=False)
Impossible de comprendre comment ajouter au code ou répondre au message, mais voici la prise en charge de Jython que vous pouvez aborder avant d'abandonner:
# jython
try:
from java.lang import Runtime
runtime = Runtime.getRuntime()
res = runtime.availableProcessors()
if res > 0:
return res
except ImportError:
pass
Vous pouvez également utiliser "joblib" à cet effet.
import joblib
print joblib.cpu_count()
Cette méthode vous donnera le nombre de processeurs dans le système. joblib doit cependant être installé. Plus d'informations sur joblib peuvent être trouvées ici https://pythonhosted.org/joblib/parallel.html
Alternativement, vous pouvez utiliser le package numexpr de python. Il a beaucoup de fonctions simples utiles pour obtenir des informations sur le processeur du système.
import numexpr as ne
print ne.detect_number_of_cores()
Une autre option si vous n'avez pas Python 2.6:
import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
/proc/<PID>/status
a quelques lignes qui vous indiquent le nombre de processeurs dans le cpuset actuel: recherchezCpus_allowed_list
.