파이썬을 사용하여 CPU 수를 찾는 방법


537

파이썬을 사용하여 로컬 컴퓨터의 CPU 수를 알고 싶습니다. 최적의 스케일링 사용자 공간 전용 프로그램으로 호출하면 결과가 user/real출력 되어야합니다 time(1).


3
Linux에서 cpusets를 명심해야합니다. CPU 세트를 사용하는 경우 아래 솔루션은 프로세스에서 사용 가능한 수가 아니라 시스템의 실제 CPU 수를 제공합니다. /proc/<PID>/status현재 cpuset의 CPU 수를 알려주는 행이 있습니다 Cpus_allowed_list.
wpoely86

답변:


854

파이썬 버전이 2.6 이상인 경우 간단히 사용할 수 있습니다.

import multiprocessing

multiprocessing.cpu_count()

http://docs.python.org/library/multiprocessing.html#multiprocessing.cpu_count


4
멀티 프로세싱은 3.x에서도 지원
LittleByBlue

3
IronPython에서 작동하지 않아 NotImplementedError가 발생한다고 덧붙이고 싶습니다.
Matthias

1
이것은 사용 가능한 CPU 수를 제공합니다 ... 프로그램에서 사용하지 않습니다!
amc

25
Python 3.6.2에서는 다음 만 사용할 수 있습니다os.cpu_count()
Achilles

4
또한 아래에 언급 된 것처럼이 수에는 "가상"하이퍼 스레딩 CPU가 포함될 수 있으며 CPU 집약적 작업을 예약하는 경우에는 원하지 않을 수 있습니다.
Christopher Barber

185

현재 프로세스에서 사용할 수있는 프로세서 에 관심이있는 경우 먼저 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'^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')

최신 Ubuntu를 실행하는 MacPro 1,0, 최근 데비안을 실행하는 HP 랩탑 및 이전 Ubuntu를 실행하는 오래된 eMachine에서 cpus_allowed 결과 /proc/self/status는 각각 ff, f 및 f-- 8, 4 및 (올바른) 수학으로 4. 그러나 실제 CPU 수는 각각 4, 2 및 1입니다. "프로세서"라는 단어의 발생 횟수를 계산 /proc/cpuinfo하는 것이 더 나은 방법 이라는 것을 알았습니다 . (또는 질문이 잘못 되었습니까?)
Mike O'Connor

1
몇 가지 추가 조사를 통해- /proc/cpuinfo"Google 검색"이라고 말할 수있는 경우- 각 "프로세서"에 대한 목록 중 하나에 대해 "형제"에 "cpu 코어"를 곱하면 "Cpus_allowed"번호를 얻습니다. 그리고 나는 형제가 하이퍼 스레딩을 참조하므로 "가상"에 대한 참조를 수집합니다. 그러나 사실은 나의 MacPro에서 "Cpus_allowed"숫자가 8 인 반면, 귀하의 multiprocessing.cpu_count()대답은 4 라는 사실이 남아 있습니다 . 저의 open('/proc/cpuinfo').read().count('processor')물리적 코어 수 (2 개의 듀얼 코어 프로세서)도 4 개가됩니다.
Mike O'Connor

1
open('/proc/self/status').read()파일을 닫는 것을 잊습니다. 사용 with open('/proc/self/status') as f: f.read()대신에
timdiels

4
os.cpu_count()
goetzc

1
@amcgregor이 경우 허용되는, 동의하며, 파일 핸들이 열려있는 상태로 오래 실행되는 데몬 / 프로세스를 작성하지 않으면 괜찮습니다. 나는 OS의 최대 열린 파일 핸들을 치는 것을 두려워 할 것입니다. 프로세스가 끝나기 전에 다시 읽어야하는 파일에 쓸 때는 상황이 더 나쁘지만 여기서는 그렇지 않습니다. with필요한 경우가 발생할 때 사용하는 습관을 갖는 것이 좋습니다 .
timdiels

91

또 다른 옵션은 psutil라이브러리 를 사용하는 것입니다. 라이브러리는 다음 상황에서 항상 유용합니다.

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

psutil(Unix 및 Windows)가 지원하는 모든 플랫폼에서 작동합니다 .

참고 어떤 경우에 있음을 multiprocessing.cpu_count인상 할 수있다 NotImplementedError동안 psutilCPU의 수를 얻을 수있을 것입니다. 이는 단순히 psutil먼저 사용 된 것과 동일한 기술을 사용하려고 시도하고 multiprocessing실패 할 경우 다른 기술도 사용하기 때문입니다.


4
이것은 사용 된 방법이 CPU 코어가 논리적 광석 물리적임을 알아낼 수 있다는 점을 고려하면 정말 좋습니다. psutil.cpu_count(logical = True)
Devilhunter

안녕하세요 @Bakuriu, psutil을 사용하여 특정 프로세스에서 사용되는 CPU 코어 수를 얻는 방법이 있습니까?
saichand

@Devilhunter 내 Intel i7-8700의 Windows에서 psutil.cpu_count()12를 제공합니다 (하이퍼 스레딩이있는 6 코어 CPU 임). 이는 기본 인수 인 logicalTrue이므로 psutil.cpu_count(logical = False)실제 코어 수를 얻으려면 명시 적으로 작성해야합니다 .
OscarVanL

52

Python 3.4 이상에서 : os.cpu_count () .

multiprocessing.cpu_count()이 함수의 관점에서 구현되지만 반환 할 NotImplementedError경우 발생 os.cpu_count()합니다 None( "CPU 수를 결정할 수 없음").


4
의 설명서도 참조하십시오 cpu_count. len(os.sched_getaffinity(0))목적에 따라 더 나을 수 있습니다.
Albert

1
@Albert 예, 시스템의 CPU 수 (—OP os.cpu_count()가 요구하는 것)는 현재 프로세스에서 사용할 수있는 CPU 수와 다를 수 있습니다 ( os.sched_getaffinity(0)).
jfs

알아. 이 차이를 놓칠 수있는 다른 독자들에게 더 완벽한 그림을 얻기 위해 이것을 추가하고 싶었습니다.
Albert

1
또한 다음은 os.sched_getaffinity(0)하지 의 사용 때문에, BSD 볼 수 있습니다 os.cpu_count()(즉, 다른 외부 라이브러리없이)가 필요합니다.
Cometsong

1
os.sched_getaffinity는 Windows에서 사용할 수없는 것 같습니다.
manu3d 2016 년

47

len(os.sched_getaffinity(0)) 당신이 보통 원하는 것입니다

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

os.sched_getaffinity(0)(Python 3에 추가)는 sched_setaffinityLinux 시스템 호출을 고려하여 사용 가능한 CPU 세트를 리턴합니다 . 이는 프로세스 및 해당 하위 프로세스에서 실행할 수있는 CPU를 제한합니다.

0현재 프로세스의 값을 얻는 것을 의미합니다. 이 함수는 set()허용 된 CPU를 반환 하므로에 필요합니다 len().

multiprocessing.cpu_count() 반면에 총 실제 CPU 수만 반환합니다.

Platform LSF 와 같은 특정 클러스터 관리 시스템은 작업 CPU 사용을 제한 하기 때문에 차이점이 특히 중요합니다 sched_getaffinity.

따라서을 사용 multiprocessing.cpu_count()하면 스크립트가 사용 가능한 것보다 많은 코어를 사용하려고 시도 할 수 있으며 이로 인해 과부하 및 시간 초과가 발생할 수 있습니다.

taskset유틸리티 와의 선호도를 제한하여 차이를 구체적으로 확인할 수 있습니다 .

예를 들어 16 코어 시스템에서 Python을 1 코어 (코어 0)로 제한하면 다음과 같습니다.

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당신이 물리적 CPU 수를 얻고 싶은 것을 덜 일반적인 경우에 대한 플래그를 :

taskset -c 0 nproc --all

이 방법의 유일한 단점은 이것이 유닉스 전용 인 것 같습니다. Windows에 유사한 유사성 API가 있어야한다고 가정 SetProcessAffinityMask했으므로 이식되지 않은 이유가 궁금합니다. 그러나 나는 Windows에 대해 아무것도 모른다.

Ubuntu 16.04, Python 3.5.2에서 테스트되었습니다.


3
유닉스에서만 사용 가능합니다.
Christopher Barber

정보에 대한 @ChristopherBarber 감사, 답변에 추가.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

33

독립적 인 플랫폼 :

psutil.cpu_count (논리 = 거짓)

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


4
논리 CPU가 아닌 논리 CPU의 차이점은 무엇입니까? 내 노트북에서 : psutil.cpu_count(logical=False) #4 psutil.cpu_count(logical=True) #8multiprocessing.cpu_count() #8
user305883

1
@ user305883 x86 CPU가 있다고 가정하면 이 머신에 하이퍼 스레딩 이 있습니다. 즉, 각 물리적 코어는 2 개의 하이퍼 스레드 ( '논리적'코어)에 해당합니다. 하이퍼 스레딩을 사용하면 물리적 코어를 사용하여 스레드 A의 일부가 유휴 상태 일 때 스레드 B의 명령을 실행할 수 있습니다 (예 : 캐시 또는 메모리에서 데이터가 페치되기를 기다리는 중). 코드에 따라 추가 코어 사용률의 1 또는 수십 퍼센트를 얻을 수 있지만 실제 물리적 코어의 성능보다 훨씬 낮습니다.
Andre Holzner

23

하이퍼 스레드 CPU 수를 제공합니다

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

이들은 가상 머신 CPU 수를 제공합니다

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

VM에서 작업하는 경우에만 중요합니다.


실제로는 아닙니다. 으로 지적, os.cpu_count()multiprocessing.cpu_count()하이퍼 스레드 CPU 개수가 아닌 실제 물리적 CPU 수를 반환합니다.
Christopher Barber

2
예. 나는 다시 말 하였다. 일반적으로 코어 수는 x 2입니다. 의미는 가상 머신을 사용하는 경우 8 개의 코어를 조각했지만 호스트 머신은 물리적으로 20 코어이며 첫 번째 명령 세트는 20, 두 번째 명령 세트는 8.
yangliu2 2016 년

21

multiprocessing.cpu_count()논리 CPU 수를 반환하므로 하이퍼 스레딩이 포함 된 쿼드 코어 CPU가 있으면를 반환 8합니다. 실제 CPU 수를 원하면 pyloc 바인딩을 사용하여 hwloc을 실행하십시오.

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

hwloc은 OS와 아키텍처에서 이식 가능하도록 설계되었습니다.


이 경우 논리 CPU 수 (즉,이 프로그램이 실제로 확장되는 경우 몇 개의 스레드를 시작해야하는지)를 원하지만 그럼에도 도움이 될 수 있습니다.
phihag

7
또는psutil.cpu_count(logical=False)
TimZaman

8

코드에 추가하거나 메시지에 회신하는 방법을 알 수 없지만 포기하기 전에 해결할 수있는 jython에 대한 지원은 다음과 같습니다.

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

7

이것은 다른 OS / 시스템을 사용하지만 모든 세계를 최대한 활용하고자하는 사람들에게 효과적 일 수 있습니다.

import os
workers = os.cpu_count()
if 'sched_getaffinity' in dir(os):
    workers = len(os.sched_getaffinity(0))

5

이 목적으로 "joblib"를 사용할 수도 있습니다.

import joblib
print joblib.cpu_count()

이 방법은 시스템의 CPU 수를 제공합니다. joblib를 설치해야합니다. joblib에 대한 자세한 내용은 https://pythonhosted.org/joblib/parallel.html을 참조하십시오.

또는 numexpr python 패키지를 사용할 수 있습니다. 시스템 CPU에 대한 정보를 얻는 데 도움이되는 간단한 기능이 많이 있습니다.

import numexpr as ne
print ne.detect_number_of_cores()

joblib은 기본 다중 처리 모듈을 사용합니다. 이를 위해 멀티 프로세싱을 직접 호출하는 것이 가장 좋습니다.
ogrisel

1

Python 2.6이없는 경우 다른 옵션 :

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

2
감사! 이것은 Linux에서만 사용할 수 있으며 이미 내 대답에 포함 되어 있습니다.
phihag
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.