Jawaban:
Jika Anda memiliki python dengan versi> = 2.6, Anda cukup menggunakan
import multiprocessing
multiprocessing.cpu_count()
http://docs.python.org/library/multiprocessing.html#multiprocessing.cpu_count
os.cpu_count()
Jika Anda tertarik dengan jumlah prosesor yang tersedia untuk proses Anda saat ini, Anda harus memeriksa cpuset terlebih dahulu. Kalau tidak (atau jika cpuset tidak digunakan), multiprocessing.cpu_count()
adalah cara untuk menggunakan Python 2.6 dan yang lebih baru. Metode berikut jatuh kembali ke beberapa metode alternatif di versi Python yang lebih lama:
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
masing-masing adalah ff, f dan f --- sesuai dengan 8, 4 dan 4 dengan matematika Anda (benar). Namun sebenarnya jumlah CPU masing-masing adalah 4, 2 dan 1. Saya menemukan bahwa menghitung jumlah kemunculan kata "prosesor" di /proc/cpuinfo
mungkin merupakan cara yang lebih baik. (Atau apakah saya memiliki pertanyaan yang salah?)
/proc/cpuinfo
itu jika untuk salah satu daftar untuk setiap "prosesor" Anda mengalikan "saudara" dengan "inti cpu" Anda mendapatkan nomor "Cpus_allowed" Anda. Dan saya berpendapat bahwa saudara kandung mengacu pada hyper-threading, maka referensi Anda untuk "virtual". Tetapi faktanya tetap bahwa nomor "Cpus_allowed" Anda adalah 8 pada MacPro saya sedangkan multiprocessing.cpu_count()
jawaban Anda adalah 4. Milik saya open('/proc/cpuinfo').read().count('processor')
juga menghasilkan 4, jumlah inti fisik (dua prosesor dual-core).
open('/proc/self/status').read()
lupa untuk menutup file. Gunakan with open('/proc/self/status') as f: f.read()
sebagai gantinya
os.cpu_count()
with
ketika Anda menemukan kasus di mana Anda membutuhkannya.
Pilihan lain adalah menggunakan psutil
perpustakaan, yang selalu bermanfaat dalam situasi ini:
>>> import psutil
>>> psutil.cpu_count()
2
Ini harus bekerja pada platform apa pun yang didukung oleh psutil
(Unix dan Windows).
Perhatikan bahwa dalam beberapa kesempatan multiprocessing.cpu_count
dapat menaikkan beberapa NotImplementedError
saat psutil
akan dapat memperoleh jumlah CPU. Ini hanya karena psutil
pertama kali mencoba menggunakan teknik yang sama yang digunakan oleh multiprocessing
dan, jika gagal, itu juga menggunakan teknik lain.
psutil.cpu_count(logical = True)
psutil.cpu_count()
memberikan 12 (ini adalah CPU 6-core dengan hyperthreading). Ini karena argumen default logical
adalah Benar, jadi Anda secara eksplisit perlu menulis psutil.cpu_count(logical = False)
untuk mendapatkan jumlah Core fisik.
Dalam Python 3.4+: os.cpu_count () .
multiprocessing.cpu_count()
diimplementasikan dalam hal fungsi ini tetapi menimbulkan NotImplementedError
jika os.cpu_count()
kembali None
("tidak dapat menentukan jumlah CPU").
cpu_count
. len(os.sched_getaffinity(0))
mungkin lebih baik, tergantung tujuannya.
os.cpu_count()
apa yang diminta OP) mungkin berbeda dari jumlah CPU yang tersedia untuk proses saat ini ( os.sched_getaffinity(0)
).
os.sched_getaffinity(0)
ini tidak tersedia di BSD, sehingga penggunaan os.cpu_count()
diperlukan (tanpa perpustakaan eksternal lainnya, yaitu).
len(os.sched_getaffinity(0))
adalah apa yang biasanya Anda inginkan
https://docs.python.org/3/library/os.html#os.sched_getaffinity
os.sched_getaffinity(0)
(ditambahkan dalam Python 3) mengembalikan set CPU yang tersedia mengingat sched_setaffinity
panggilan sistem Linux , yang membatasi CPU mana proses dan anak-anaknya dapat berjalan.
0
artinya mendapatkan nilai untuk proses saat ini. Fungsi mengembalikan a set()
dari CPU yang diizinkan, sehingga perlu len()
.
multiprocessing.cpu_count()
di sisi lain hanya mengembalikan jumlah total CPU fisik.
Perbedaan ini sangat penting karena sistem manajemen cluster tertentu seperti Platform LSF membatasi penggunaan CPU dengan pekerjaan sched_getaffinity
.
Oleh karena itu, jika Anda menggunakan multiprocessing.cpu_count()
, skrip Anda mungkin mencoba menggunakan lebih banyak core daripada yang tersedia, yang dapat menyebabkan kelebihan muatan dan batas waktu.
Kita dapat melihat perbedaan secara konkret dengan membatasi afinitas dengan taskset
utilitas.
Sebagai contoh, jika saya membatasi Python hanya 1 core (core 0) di sistem 16 core saya:
taskset -c 0 ./main.py
dengan skrip uji:
main.py
#!/usr/bin/env python3
import multiprocessing
import os
print(multiprocessing.cpu_count())
print(len(os.sched_getaffinity(0)))
maka outputnya adalah:
16
1
nproc
namun demikian menghargai afinitas secara default dan:
taskset -c 0 nproc
output:
1
dan man nproc
membuatnya cukup eksplisit:
cetak jumlah unit pemrosesan yang tersedia
nproc
memiliki --all
tanda untuk kasus yang kurang umum yang ingin Anda peroleh hitungan CPU fisik:
taskset -c 0 nproc --all
Satu-satunya downside dari metode ini adalah bahwa ini tampaknya hanya UNIX. Saya kira Windows harus memiliki API afinitas yang sama, mungkin SetProcessAffinityMask
, jadi saya bertanya-tanya mengapa itu belum porting. Tapi saya tidak tahu apa-apa tentang Windows.
Diuji dalam Ubuntu 16.04, Python 3.5.2.
Jika Anda ingin mengetahui jumlah core fisik (bukan core hyperthreaded virtual), berikut adalah solusi platform independen:
psutil.cpu_count(logical=False)
https://github.com/giampaolo/psutil/blob/master/INSTALL.rst
Perhatikan bahwa nilai default untuk logical
adalah True
, jadi jika Anda ingin memasukkan core yang dapat di hiphread, Anda dapat menggunakan:
psutil.cpu_count()
Ini akan memberikan nomor yang sama dengan os.cpu_count()
dan multiprocessing.cpu_count()
, tidak ada yang memiliki logical
argumen kata kunci.
psutil.cpu_count(logical=False) #4
psutil.cpu_count(logical=True) #8
danmultiprocessing.cpu_count() #8
Ini memberi Anda jumlah CPU hyperthreaded
multiprocessing.cpu_count()
os.cpu_count()
Ini memberi Anda jumlah CPU mesin virtual
psutil.cpu_count()
numexpr.detect_number_of_cores()
Hanya masalah jika Anda bekerja pada VM.
os.cpu_count()
dan multiprocessing.cpu_count()
akan mengembalikan jumlah cpu yang di-hiphread, bukan jumlah cpu fisik yang sebenarnya.
multiprocessing.cpu_count()
akan mengembalikan jumlah CPU logis, jadi jika Anda memiliki CPU quad-core dengan hyperthreading, itu akan kembali 8
. Jika Anda ingin jumlah CPU fisik, gunakan binding python ke hwloc:
#!/usr/bin/env python
import hwloc
topology = hwloc.Topology()
topology.load()
print topology.get_nbobjs_by_type(hwloc.OBJ_CORE)
hwloc dirancang untuk portabel di seluruh OS dan arsitektur.
psutil.cpu_count(logical=False)
Tidak dapat menemukan cara menambahkan kode atau membalas pesan, tetapi inilah dukungan untuk jython yang dapat Anda tempel sebelum menyerah:
# jython
try:
from java.lang import Runtime
runtime = Runtime.getRuntime()
res = runtime.availableProcessors()
if res > 0:
return res
except ImportError:
pass
Anda juga dapat menggunakan "joblib" untuk tujuan ini.
import joblib
print joblib.cpu_count()
Metode ini akan memberi Anda jumlah CPU dalam sistem. joblib perlu diinstal. Informasi lebih lanjut tentang joblib dapat ditemukan di sini https://pythonhosted.org/joblib/parallel.html
Atau Anda dapat menggunakan paket numexpr dari python. Ini memiliki banyak fungsi sederhana yang membantu untuk mendapatkan informasi tentang cpu sistem.
import numexpr as ne
print ne.detect_number_of_cores()
Opsi lain jika Anda tidak memiliki Python 2.6:
import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
/proc/<PID>/status
memiliki beberapa baris yang memberitahu Anda jumlah CPU di cpuset saat ini: cariCpus_allowed_list
.