web-dev-qa-db-ja.com

pythonを使ってCPUの数を調べる方法

私はPythonを使ってローカルマシン上のCPUの数を知りたいのです。最適にスケーリングされるユーザースペースのみのプログラムで呼び出されると、結果はtime(1)による出力としてuser/realになるはずです。

428
phihag

現在のプロセスで利用可能なプロセッサの数に興味がある場合は、 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')
164
phihag

バージョン2.6以上のpythonを使っているなら、単純に使うことができます。

import multiprocessing

multiprocessing.cpu_count()

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

728
Nadia Alramli

別の選択肢は psutil ライブラリを使うことです。

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

これはpsutil(UnixとWindows)でサポートされているどのプラットフォームでも動作するはずです。

場合によってはmultiprocessing.cpu_countNotImplementedErrorを上げることがありますが、psutilはCPUの数を取得することができます。これは単にpsutilが最初にmultiprocessingと同じテクニックを使用しようとし、それが失敗した場合には他のテクニックも使用するからです。

75
Bakuriu

Python 3.4以降の場合: os.cpu_count()

multiprocessing.cpu_count()はこの関数の観点から実装されていますが、os.cpu_count()NotImplementedErrorを返す場合( "CPUの数を決定できません")、Noneが発生します。

36
jfs
import os

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

プラットフォームに依存しない

psutil.cpu_count(logical = False)

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

26

multiprocessing.cpu_count()は論理CPUの数を返すので、ハイパースレッディング付きのクアッドコアCPUがある場合は8を返します。物理CPUの数が欲しいなら、hwlocにpythonバインディングを使います。

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

hwlocはOSとアーキテクチャ間で移植性があるように設計されています。

16

len(os.sched_getaffinity(0))はあなたが通常欲しいものです

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

(Python 3で追加された)os.sched_getaffinity(0)sched_setaffinity Linuxシステムコール を考慮して利用可能なCPUのセットを返します。 。

0は現在のプロセスの値を取得することを意味します。この関数は許可されたCPUのset()を返すので、len()が必要です。

一方、multiprocessing.cpu_count()は単に物理CPUの総数を返します。

Platform LSF などの特定のクラスタ管理システムでは、sched_getaffinityでジョブのCPU使用率が制限されるため、この違いは特に重要です。

そのため、multiprocessing.cpu_count()を使用すると、スクリプトは使用可能なコアよりも多くのコアを使用しようとする可能性があり、それが過負荷やタイムアウトにつながる可能性があります。

tasksetユーティリティでアフィニティを制限することで、違いを具体的に確認できます。

たとえば、16コアシステムでPythonを1コア(core 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には、物理​​的なCPU数を取得したいという、あまり一般的ではない場合のための--allフラグがあります。

taskset -c 0 nproc --all

この方法の唯一の欠点は、これがUNIXだけのように見えることです。私は、おそらく SetProcessAffinityMask のように、Windowsにも同様のアフィニティAPIがなければならないと思いました。しかし、私はWindowsについては何も知りません。

Ubuntu 16.04、Python 3.5.2でテスト済み。

コードを追加したりメッセージに返信したりする方法を理解することはできませんが、あきらめる前にあなたが取り組むことができるjythonのサポートは次のとおりです。

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

この目的のために "joblib"を使うこともできます。

import joblib
print joblib.cpu_count()

このメソッドはあなたにシステムのCPUの数を与えます。 joblibもインストールする必要があります。 joblibの詳細については、こちら を参照してください。https://pythonhosted.org/joblib/parallel.html

あるいはpythonのnumexprパッケージを使うこともできます。システムCPUに関する情報を取得するのに役立つ単純な機能がたくさんあります。

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

まだコメントできないので

これらはあなたにハイパースレッドCPU数を与えます

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

これらにより、仮想マシンのCPU数がわかります。

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

あなたがVMで作業している場合にのみ重要です。

3
yangliu2

これはマルチプロセッシングからの関数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')
1
user9177539

あなたがPython 2.6を持っていないならば、もう一つの選択肢:

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