Question

Je souhaite connaître le nombre de processeurs sur la machine locale utilisant Python. Le résultat doit être utilisateur / réel , généré par time (1) lorsqu'il est appelé avec un programme dimensionnant uniquement l'espace utilisateur.

Était-ce utile?

La solution 2

Si le nombre de processeurs disponibles dans votre processus actuel vous intéresse, vous devez vérifier cpuset en premier. Sinon (ou si cpuset n'est pas utilisé), multiprocessing.cpu_count () est la voie à suivre dans Python 2.6 et les versions plus récentes. La méthode suivante a recours à plusieurs 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')

Autres conseils

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

Une autre option consiste à utiliser la bibliothèque psutil , qui s'avère toujours utile dans ces situations:

>>> import psutil
>>> psutil.cpu_count()
2

Ceci devrait fonctionner sur toute plate-forme prise en charge par psutil (Unix et Windows).

Notez que dans certaines occasions, multiprocessing.cpu_count peut générer un NotImplementedError alors que psutil pourra obtenir le nombre de processeurs. C’est simplement parce que psutil essaie d’abord d’utiliser les mêmes techniques que celles utilisées par le multitraitement et, si elles échouent, il utilise également d’autres techniques.

Dans Python 3.4+: os.cpu_count () .

multiprocessing.cpu_count () est implémenté en termes de cette fonction, mais déclenche NotImplementedError si os.cpu_count () renvoie Aucun ("Impossible de déterminer le nombre de processeurs").

import os

print(os.cpu_count())

indépendant de la plateforme:

  

psutil.cpu_count (logical = False)

https://github.com/giampaolo/psutil/blob/master/INSTALL.rst

multiprocessing.cpu_count () renverra le nombre de processeurs logiques. Ainsi, si vous avez un processeur quad-core avec hyperthreading, il renverra 8 . Si vous souhaitez connaître le nombre de processeurs physiques, utilisez les liaisons python à 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 plusieurs systèmes d’exploitation et architectures.

len (os.sched_getaffinity (0)) est ce que vous voulez habituellement

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 du sched_setaffinity appel système Linux , qui limite les processeurs et leurs processus les enfants peuvent courir.

0 signifie obtenir la valeur du processus en cours. La fonction renvoie un set () des processeurs autorisés, d'où la nécessité de len () .

multiprocessing.cpu_count () , en revanche, renvoie simplement le nombre total de processeurs physiques.

La différence est particulièrement importante car certains systèmes de gestion de grappes, tels que les Platform LSF , limitent le nombre de processeurs. utilisation avec sched_getaffinity .

Par conséquent, si vous utilisez multiprocessing.cpu_count () , votre script peut essayer d'utiliser beaucoup plus de cœurs que ce dont il dispose, ce qui peut entraîner une surcharge et des délais.

Nous pouvons voir la différence concrètement en limitant l'affinité avec l'utilitaire taskset .

Par exemple, si je limite Python à un seul noyau (core 0) dans mon système à 16 noyaux:

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 le résultat est:

16
1

nproc respecte l'affinité par défaut:

taskset -c 0 nproc

sorties:

1

et man nproc rendent cela très explicite:

  

imprimer le nombre d'unités de traitement disponibles

nproc a le drapeau - all pour le cas le moins fréquent où vous souhaitez obtenir le nombre de CPU physique:

taskset -c 0 nproc --all

Le seul inconvénient de cette méthode est qu’il ne s’agit que d’UNIX. Je suppose que Windows doit disposer d'une API d'affinité similaire, éventuellement SetProcessAffinityMask , je me demande donc pourquoi il n'a pas été porté. Mais je ne connais rien de Windows.

Testé sous Ubuntu 16.04, Python 3.5.2.

Vous ne savez pas comment ajouter du code ou répondre au message, mais voici le support technique pour jython que vous pouvez intégrer 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 " dans ce but.

import joblib
print joblib.cpu_count()

Cette méthode vous donnera le nombre de processeurs du système. joblib doit cependant être installé. Pour plus d'informations sur joblib, cliquez ici https://pythonhosted.org/joblib/parallel.html .

Vous pouvez également utiliser le package numexpr de python. Il contient de nombreuses fonctions simples utiles pour obtenir des informations sur le processeur système.

import numexpr as ne
print ne.detect_number_of_cores()

Ils vous donnent le nombre de processeurs hyperthreaded

  1. multiprocessing.cpu_count ()
  2. os.cpu_count ()

Ils vous donnent le nombre de processeurs de la machine virtuelle

  1. psutil.cpu_count ()
  2. numexpr.detect_number_of_cores ()

Ne compte que si vous travaillez sur des ordinateurs virtuels.

Une autre option si vous n'avez pas Python 2.6:

import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top