回答:
バージョン2.6以上のpythonを使用している場合は、次のように使用できます。
import multiprocessing
multiprocessing.cpu_count()
http://docs.python.org/library/multiprocessing.html#multiprocessing.cpu_count
os.cpu_count()
現在のプロセスで利用可能なプロセッサの数に興味がある場合は、最初に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')
/proc/self/status
はそれぞれff、f、f ---で、それぞれ8、4 および(正しい)数学による4。ただし、CPUの実際の数はそれぞれ4、2、1です。「プロセッサー」という単語の出現回数を数えるの/proc/cpuinfo
が良い方法だと思います。(または、質問が間違っていますか?)
/proc/cpuinfo
と言えば、「プロセッサー」のリストのいずれかで「兄弟」に「CPUコア」を掛けると、その使用からわかります。 「Cpus_allowed」番号を取得します。そして、私は兄弟がハイパースレッディングを参照しているので、「仮想」への参照を収集しています。しかし、私のMacProでは「Cpus_allowed」の数が8であるのに対し、あなたのmultiprocessing.cpu_count()
答えは4であるという事実が残っています。私自身open('/proc/cpuinfo').read().count('processor')
も4の物理コア(2つのデュアルコアプロセッサ)を生成します。
open('/proc/self/status').read()
ファイルを閉じるのを忘れました。with open('/proc/self/status') as f: f.read()
代わりに使用
os.cpu_count()
with
あなたがそれを必要とするケースに遭遇したときに使用する習慣をつけるのは良い考えです。
もう1つのオプションは、psutil
ライブラリを使用することです。これは、常に次のような状況で役立ちます。
>>> import psutil
>>> psutil.cpu_count()
2
これは、psutil
(UNIXおよびWindows)でサポートされているすべてのプラットフォームで機能します。
場合multiprocessing.cpu_count
によっては、CPUの数を取得できるまでNotImplementedError
しばらく時間psutil
がかかることがあります。これは単に、psutil
最初にと同じテクニックを使用しようとするためでmultiprocessing
あり、失敗した場合は他のテクニックも使用するためです。
psutil.cpu_count(logical = True)
psutil.cpu_count()
12(ハイパースレッディングを備えた6コアCPU)を提供します。これは、デフォルトの引数logical
がTrueであるためpsutil.cpu_count(logical = False)
、物理コアの数を取得するために明示的に書き込む必要があるためです。
Python 3.4以降の場合:os.cpu_count()。
multiprocessing.cpu_count()
この関数の観点から実装されていますがNotImplementedError
、os.cpu_count()
戻る場合に発生しますNone
(「CPUの数を判別できません」)。
cpu_count
。len(os.sched_getaffinity(0))
目的によってはより良いかもしれません。
os.cpu_count()
OPが要求するもの)は、現在のプロセスで使用可能なCPUの数とは異なる場合があります(os.sched_getaffinity(0)
)。
os.sched_getaffinity(0)
ありませんの使用ので、BSD上で利用可能os.cpu_count()
です(つまり、他の外部ライブラリなし)が必要です。
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のa を返すため、の必要性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
この方法の唯一の欠点は、これがUNIXのみのように見えることです。Windowsにも同様のアフィニティAPIが必要だと思います。SetProcessAffinityMask
)が必要だと思っていたので、移植されていないのはなぜでしょうか。しかし、私はWindowsについて何も知りません。
Ubuntu 16.04、Python 3.5.2でテスト済み。
物理コア(仮想ハイパースレッドコアではない)の数を知りたい場合は、プラットフォームに依存しないソリューションを次に示します。
psutil.cpu_count(logical=False)
https://github.com/giampaolo/psutil/blob/master/INSTALL.rst
のデフォルト値logical
はTrue
なので、ハイパースレッドコアを含める場合は、次のように使用できます。
psutil.cpu_count()
これにより、os.cpu_count()
およびと同じ数が得られますがmultiprocessing.cpu_count()
、どちらにもlogical
キーワード引数はありません。
psutil.cpu_count(logical=False) #4
psutil.cpu_count(logical=True) #8
およびmultiprocessing.cpu_count() #8
これらはあなたにハイパースレッドのCPU数を与えます
multiprocessing.cpu_count()
os.cpu_count()
これらは仮想マシンのCPUカウントを提供します
psutil.cpu_count()
numexpr.detect_number_of_cores()
VMで作業する場合にのみ問題になります。
os.cpu_count()
及びmultiprocessing.cpu_count()
ハイパースレッドCPUの数ではなく、実際の物理CPU数を返します。
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およびアーキテクチャ間で移植できるように設計されています。
psutil.cpu_count(logical=False)
この目的で「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()
Python 2.6がない場合の別のオプション:
import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
/proc/<PID>/status
現在のcpuset内のCPUの数を示すいくつかの行がありますCpus_allowed_list
。