Подтвердить что ты не робот

Как узнать количество процессоров, использующих python

Я хочу знать количество процессоров на локальной машине с помощью Python. Результат должен быть user/real в качестве вывода time(1) при вызове с оптимальным масштабированием программы только для пользовательского пространства.

4b9b3361

Ответ 1

Если вас интересует количество процессоров, доступных вашему текущему процессу, вам сначала нужно проверить cpuset. В противном случае (или если cpuset не используется), multiprocessing.cpu_count() - это путь в Python 2.6 и новее. Следующий метод возвращается к паре альтернативных методов в старых версиях 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'^[email protected][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')

Ответ 3

Другой вариант - использовать библиотеку psutil, которая всегда psutil полезной в следующих ситуациях:

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

Это должно работать на любой платформе, поддерживаемой psutil (Unix и Windows).

Обратите внимание, что в некоторых случаях multiprocessing.cpu_count может вызвать NotImplementedError тогда как psutil сможет получить количество процессоров. Это просто потому, что psutil сначала пытается использовать те же методы, что и multiprocessing и, если они не psutil, он также использует другие методы.

Ответ 4

В Python 3.4+: os.cpu_count().

multiprocessing.cpu_count() реализуется с точки зрения этой функции, но вызывает NotImplementedError, если os.cpu_count() возвращает None ( "не может определить количество процессоров" ).

Ответ 5

import os

print(os.cpu_count())

Ответ 7

multiprocessing.cpu_count() вернет количество логических процессоров, поэтому, если у вас есть четырехъядерный процессор с гиперпотоком, он вернет 8. Если вы хотите количество физических процессоров, используйте привязки python для hwloc:

#!/usr/bin/env python
import hwloc
topology = hwloc.Topology()
topology.load()
print topology.get_nbobjs_by_type(hwloc.OBJ_CORE)

hwloc предназначен для переносимости по всем операционным системам и архитектурам.

Ответ 8

len(os.sched_getaffinity(0)) - это то, что вы обычно хотите

https://docs.python.org/3/library/os.html#os.sched_getaffinity

os.sched_getaffinity(0) (добавлено в Python 3) возвращает набор доступных процессоров с учетом системного вызова sched_setaffinity Linux, который ограничивает, на каких процессорах процесс и его дочерние элементы могут работать.

0 означает получить значение для текущего процесса. Функция возвращает set() разрешенных процессоров, таким образом, необходимость в len().

multiprocessing.cpu_count() с другой стороны, просто возвращает общее количество физических процессоров.

Разница особенно важна, потому что некоторые системы управления кластером, такие как платформа LSF, ограничивают использование ЦП заданием с sched_getaffinity.

Поэтому, если вы используете multiprocessing.cpu_count(), ваш скрипт может попытаться использовать больше ядер, чем у него есть, что может привести к перегрузке и тайм-аутам.

Мы можем увидеть разницу конкретно, ограничив сродство утилитой taskset.

Например, если я ограничу Python только одним ядром (ядро 0) в моей 16-ядерной системе:

taskset -c 0 ./main.py

с тестовым скриптом:

main.py

#!/usr/bin/env python3

import multiprocessing
import os

print(multiprocessing.cpu_count())
print(len(os.sched_getaffinity(0)))

тогда вывод:

16
1

nproc уважает сходство по умолчанию:

taskset -c 0 nproc

выходы:

1

и man nproc делает это довольно явно:

распечатать количество доступных единиц обработки

nproc есть флаг --all для менее распространенного случая, когда вы хотите получить физический счетчик ЦП:

taskset -c 0 nproc --all

Единственным недостатком этого метода является то, что это только UNIX. Я предположил, что в Windows должен быть похожий API-интерфейс, возможно SetProcessAffinityMask, поэтому мне интересно, почему он не был портирован. Но я ничего не знаю о Windows.

Протестировано в Ubuntu 16.04, Python 3.5.2.

Ответ 9

Невозможно выяснить, как добавить код или ответить на сообщение, но вот поддержка jython, с которой вы можете столкнуться, прежде чем отказаться:

# jython
try:
    from java.lang import Runtime
    runtime = Runtime.getRuntime()
    res = runtime.availableProcessors()
    if res > 0:
        return res
except ImportError:
    pass

Ответ 10

Для этой цели вы также можете использовать "joblib".

import joblib
print joblib.cpu_count()

Этот метод даст вам количество процессоров в системе. joblib должен быть установлен. Более подробную информацию о joblib можно найти здесь https://pythonhosted.org/joblib/parallel.html

В качестве альтернативы вы можете использовать пакет numexpr для python. Он имеет множество простых функций, полезных для получения информации о системном процессоре.

import numexpr as ne
print ne.detect_number_of_cores()

Ответ 11

Они дают вам подсчитанное количество процессоров

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

Они дают вам количество процессоров виртуальной машины

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

Имеет значение только если вы работаете на виртуальных машинах.

Ответ 12

Другой вариант, если у вас нет Python 2.6:

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

Ответ 13

Это функция cpu_count из многопроцессорной

:}

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')