web-dev-qa-db-fra.com

Comment connaître le nombre de processeurs utilisant python

Je veux connaître le nombre de processeurs sur la machine locale utilisant Python. Le résultat doit être user/real comme sortie de time(1) lorsqu'il est appelé avec un programme à mise à l'échelle optimale de l'espace utilisateur.

449
phihag

Si vous êtes intéressé par le nombre de processeurs disponibles par rapport à votre processus actuel, vous devez d'abord vérifier cpuset . Sinon (ou si cpuset n'est pas utilisé), multiprocessing.cpu_count() est le chemin à parcourir dans Python 2.6 et plus récent. 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')
166
phihag

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

751
Nadia Alramli

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

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

Cela devrait fonctionner sur n’importe quelle plate-forme supportée par psutil (Unix et Windows).

Notez que dans certaines occasions, multiprocessing.cpu_count peut générer un NotImplementedError tandis 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 multiprocessing et, si celles-ci échouent, il utilise également d’autres techniques.

77
Bakuriu

Dans Python 3.4+: os.cpu_count () .

multiprocessing.cpu_count() est implémenté en termes de cette fonction mais soulève NotImplementedError si os.cpu_count() renvoie None ("ne peut pas déterminer le nombre de CPU").

40
jfs
import os

print(os.cpu_count())
29
Khalil Al Hooti

plateforme indépendante:

psutil.cpu_count (logical = False)

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

27

multiprocessing.cpu_count() renvoie le nombre de processeurs logiques. Ainsi, si vous disposez d'un processeur quad-core avec hyperthreading, il renverra 8. Si vous souhaitez connaître le nombre de processeurs physiques, utilisez les liaisons python avec 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.

18
Douglas B. Staple

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 en considérant sched_setaffinity appel système Linux , ce qui limite les processeurs et leurs enfants. peut courir sur.

0 signifie obtenir la valeur du processus en cours. La fonction retourne une set() des CPU autorisées, d'où la nécessité de len().

multiprocessing.cpu_count(), d'autre part, renvoie simplement le nombre total de processeurs physiques.

La différence est particulièrement importante car certains systèmes de gestion de grappe, tels que Platform LSF , limitent l’utilisation de la CPU par le travail 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 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 toutefois l’affinité par défaut et:

taskset -c 0 nproc

les sorties:

1

et man nproc rend 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 que cela semble être uniquement UNIX. Je suppose que Windows doit avoir une API d'affinité similaire, éventuellement SetProcessAffinityMask , alors je me demande pourquoi elle n'a pas été portée. Mais je ne connais rien de Windows.

Testé sous Ubuntu 16.04, Python 3.5.2.

Ceux-ci vous donnent le nombre de CPU hyperthreaded

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

Ceux-ci vous donnent le nombre de CPU de la machine virtuelle

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

Ne compte que si vous travaillez sur des VM.

9
yangliu2

Vous ne savez pas comment ajouter au code ou comment 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
7
Ben Scherrey

Vous pouvez également utiliser "joblib" à cette fin.

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

Sinon, vous pouvez utiliser le paquet numexpr de python. Il a beaucoup de fonctions simples utiles pour obtenir des informations sur le processeur système.

import numexpr as ne
print ne.detect_number_of_cores()
5
amit12690

C'est la fonction cpu_count du multitraitement

:}

import os
import sys

def cpu_count():
    '''
    Returns the number of CPUs in the system
    '''
    if sys.platform == 'win32':
        try:
            num = int(os.environ['NUMBER_OF_PROCESSORS'])
        except (ValueError, KeyError):
            num = 0
    Elif 'bsd' in sys.platform or sys.platform == 'darwin':
        comm = '/sbin/sysctl -n hw.ncpu'
        if sys.platform == 'darwin':
            comm = '/usr' + comm
        try:
            with os.popen(comm) as p:
                num = int(p.read())
        except ValueError:
            num = 0
    else:
        try:
            num = os.sysconf('SC_NPROCESSORS_ONLN')
        except (ValueError, OSError, AttributeError):
           num = 0

    if num >= 1:
        return num
    else:
        raise NotImplementedError('cannot determine number of cpus')
1
user9177539

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

import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
1
Alkero