質問

Pythonを使用してローカルマシンのCPU数を知りたいです。結果は次のようになります。 user/real による出力として time(1) 最適にスケーリングするユーザー空間のみのプログラムで呼び出された場合。

役に立ちましたか?

解決 2

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

他のヒント

Pythonのバージョンが> = 2.6の場合は、単に使用できます

import multiprocessing

multiprocessing.cpu_count()

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

別のオプションは、 psutil ライブラリを使用することです。これらの状況で役立ちます:

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

これは、 psutil (UnixおよびWindows)でサポートされているすべてのプラットフォームで動作するはずです。

場合によっては、 multiprocessing.cpu_count NotImplementedError を発生させ、 psutil がCPUの数を取得できる場合があることに注意してください。これは、単に psutil が最初に multiprocessing で使用されるのと同じ手法を使用しようとし、失敗した場合は他の手法も使用するためです。

Python 3.4以降: os.cpu_count()

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

import os

print(os.cpu_count())

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

  

psutil.cpu_count(logical = False)

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

multiprocessing.cpu_count()は論理CPUの数を返します。したがって、ハイパースレッディングを備えたクアッドコアCPUがある場合、 8 を返します。物理CPUの数が必要な場合は、pythonバインディングを使用してhwlocに追加します。

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

hwlocは、OSおよびアーキテクチャ間で移植できるように設計されています。

len(os.sched_getaffinity(0)) それはあなたが通常望むものです

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

os.sched_getaffinity(0) (Python 3 で追加) を考慮して利用可能な CPU のセットを返します。 sched_setaffinity Linuxシステムコール, 、プロセスとその子を実行できる CPU を制限します。

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

multiprocessing.cpu_count() 一方、物理 CPU の合計数を返すだけです。

などの特定のクラスター管理システムでは、この違いが特に重要です。 プラットフォーム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

この方法の唯一の欠点は、これが UNIX のみであるように見えることです。おそらく Windows にも同様のアフィニティ API があるはずだと思いました。 SetProcessAffinityMask, 、なぜ移植されないのか不思議です。しかし、私は 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

" 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()

これらはハイパースレッドCPUカウントを提供します

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

これらは仮想マシンのCPUカウントを提供します

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

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

Python 2.6がない場合の別のオプション:

import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top