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.

War es hilfreich?

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)

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

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

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

Diese geben Sie die virtuelle Maschine CPU-Anzahl

  1. psutil.cpu_count()
  2. 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")
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top