Pythonを使用してCPUの数を調べる方法
-
06-07-2019 - |
質問
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を返す場合、
(" CPUの数を決定できません")。 NotImplementedError
を発生させます
import os
print(os.cpu_count())
プラットフォームに依存しない:
psutil.cpu_count(logical = False)
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カウントを提供します
-
multiprocessing.cpu_count()
-
os.cpu_count()
これらは仮想マシンのCPUカウントを提供します
-
psutil.cpu_count()
-
numexpr.detect_number_of_cores()
VMで作業している場合にのみ重要です。
Python 2.6がない場合の別のオプション:
import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")