Câu trả lời:
Nếu bạn có python với phiên bản> = 2.6, bạn chỉ cần sử dụng
import multiprocessing
multiprocessing.cpu_count()
http://docs.python.org/l Library / multiprocessing.html # multiprocessing.cpu_count
os.cpu_count()
Nếu bạn quan tâm đến số lượng bộ xử lý có sẵn cho quy trình hiện tại của mình, trước tiên bạn phải kiểm tra cpuset . Mặt khác (hoặc nếu cpuset không được sử dụng), multiprocessing.cpu_count()
là cách để đi trong Python 2.6 và mới hơn. Phương thức sau đây quay lại một vài phương thức thay thế trong các phiên bản cũ hơn của 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
tương ứng là ff, f và f --- tương ứng với 8, 4 và 4 bằng toán học (chính xác) của bạn. Tuy nhiên, số lượng CPU thực tế tương ứng là 4, 2 và 1. Tôi thấy rằng việc đếm số lần xuất hiện của từ "bộ xử lý" /proc/cpuinfo
có thể là cách tốt hơn để đi. (Hay tôi có câu hỏi sai?)
/proc/cpuinfo
nó nếu với bất kỳ một danh sách nào cho mỗi "bộ xử lý", bạn nhân "anh chị em" với "lõi cpu" bạn nhận được số "Cpus_allowed" của mình. Và tôi tập hợp rằng các anh chị em đề cập đến siêu phân luồng, do đó bạn tham khảo "ảo". Nhưng sự thật vẫn là số "Cpus_allowed" của bạn là 8 trên MacPro của tôi trong khi multiprocessing.cpu_count()
câu trả lời của bạn là 4. Riêng tôi open('/proc/cpuinfo').read().count('processor')
cũng tạo ra 4, số lõi vật lý (hai bộ xử lý lõi kép).
open('/proc/self/status').read()
quên đóng tập tin Sử dụng with open('/proc/self/status') as f: f.read()
thay thế
os.cpu_count()
with
khi bạn gặp phải trường hợp bạn cần.
Một tùy chọn khác là sử dụng psutil
thư viện, vốn luôn hữu ích trong các tình huống sau:
>>> import psutil
>>> psutil.cpu_count()
2
Điều này sẽ hoạt động trên mọi nền tảng được hỗ trợ bởi psutil
(Unix và Windows).
Lưu ý rằng trong một số trường hợp multiprocessing.cpu_count
có thể tăng một NotImplementedError
thời gian psutil
sẽ có thể có được số lượng CPU. Điều này đơn giản là vì psutil
lần đầu tiên cố gắng sử dụng các kỹ thuật tương tự được sử dụng bởi multiprocessing
và nếu thất bại, nó cũng sử dụng các kỹ thuật khác.
psutil.cpu_count(logical = True)
psutil.cpu_count()
cho 12 (đó là CPU 6 lõi với khả năng siêu phân luồng). Điều này là do đối số mặc định logical
là True, do đó bạn cần phải viết rõ ràng psutil.cpu_count(logical = False)
để có được số lượng Cores vật lý.
Trong Python 3,4+ : os.cpu_count () .
multiprocessing.cpu_count()
được triển khai theo chức năng này nhưng tăng NotImplementedError
nếu os.cpu_count()
trả về None
("không thể xác định số lượng CPU").
cpu_count
. len(os.sched_getaffinity(0))
có thể tốt hơn, tùy thuộc vào mục đích.
os.cpu_count()
Yêu cầu OP yêu cầu) có thể khác với số lượng CPU có sẵn cho quy trình hiện tại ( os.sched_getaffinity(0)
).
os.sched_getaffinity(0)
là không có sẵn trên BSD, vì vậy việc sử dụng các os.cpu_count()
yêu cầu (không có thư viện bên ngoài khác, đó là).
len(os.sched_getaffinity(0))
là những gì bạn thường muốn
https://docs.python.org/3/l Library / os.html # os.sched_getaffinity
os.sched_getaffinity(0)
(được thêm vào trong Python 3) trả về bộ CPU có sẵn khi xem xét sched_setaffinity
cuộc gọi hệ thống Linux , giới hạn CPU mà một quá trình và con của nó có thể chạy.
0
có nghĩa là để có được giá trị cho quá trình hiện tại. Hàm trả về một set()
CPU được phép, do đó cần phải có len()
.
multiprocessing.cpu_count()
mặt khác chỉ trả về tổng số CPU vật lý.
Sự khác biệt đặc biệt quan trọng vì các hệ thống quản lý cụm nhất định như Nền tảng LSF giới hạn việc sử dụng CPU công việc sched_getaffinity
.
Do đó, nếu bạn sử dụng multiprocessing.cpu_count()
, tập lệnh của bạn có thể cố gắng sử dụng nhiều lõi hơn mức có sẵn, điều này có thể dẫn đến quá tải và hết thời gian.
Chúng ta có thể thấy sự khác biệt một cách cụ thể bằng cách hạn chế mối quan hệ với taskset
tiện ích.
Ví dụ: nếu tôi giới hạn Python chỉ 1 lõi (lõi 0) trong hệ thống 16 lõi của mình:
taskset -c 0 ./main.py
với kịch bản thử nghiệm:
chính
#!/usr/bin/env python3
import multiprocessing
import os
print(multiprocessing.cpu_count())
print(len(os.sched_getaffinity(0)))
thì đầu ra là:
16
1
nproc
tuy nhiên, tôn trọng mối quan hệ theo mặc định và:
taskset -c 0 nproc
đầu ra:
1
và man nproc
làm cho điều đó khá rõ ràng:
in số lượng đơn vị xử lý có sẵn
nproc
có --all
cờ cho trường hợp ít phổ biến hơn mà bạn muốn lấy số lượng CPU vật lý:
taskset -c 0 nproc --all
Nhược điểm duy nhất của phương pháp này là nó dường như chỉ là UNIX. Tôi nghĩ rằng Windows phải có API mối quan hệ tương tự, có thể SetProcessAffinityMask
, vì vậy tôi tự hỏi tại sao nó không được chuyển. Nhưng tôi không biết gì về Windows.
Đã thử nghiệm trong Ubuntu 16.04, Python 3.5.2.
nền tảng độc lập:
psutil.cpu_count (logic = Sai)
psutil.cpu_count(logical=False) #4
psutil.cpu_count(logical=True) #8
vàmultiprocessing.cpu_count() #8
Chúng cung cấp cho bạn số lượng CPU siêu phân luồng
multiprocessing.cpu_count()
os.cpu_count()
Chúng cung cấp cho bạn số lượng CPU máy ảo
psutil.cpu_count()
numexpr.detect_number_of_cores()
Chỉ quan trọng nếu bạn làm việc trên máy ảo.
os.cpu_count()
và multiprocessing.cpu_count()
sẽ trả về số lượng cpu siêu phân luồng, chứ không phải số lượng cpu vật lý thực tế.
multiprocessing.cpu_count()
sẽ trả về số lượng CPU logic, vì vậy nếu bạn có CPU lõi tứ với siêu phân luồng, nó sẽ trả về 8
. Nếu bạn muốn số lượng CPU vật lý, hãy sử dụng các liên kết python để hwloc:
#!/usr/bin/env python
import hwloc
topology = hwloc.Topology()
topology.load()
print topology.get_nbobjs_by_type(hwloc.OBJ_CORE)
hwloc được thiết kế để có thể di động trên các hệ điều hành và kiến trúc.
psutil.cpu_count(logical=False)
Không thể tìm ra cách thêm mã hoặc trả lời tin nhắn nhưng đây là hỗ trợ cho jython mà bạn có thể giải quyết trước khi bạn từ bỏ:
# jython
try:
from java.lang import Runtime
runtime = Runtime.getRuntime()
res = runtime.availableProcessors()
if res > 0:
return res
except ImportError:
pass
Bạn cũng có thể sử dụng "joblib" cho mục đích này.
import joblib
print joblib.cpu_count()
Phương pháp này sẽ cung cấp cho bạn số lượng cpus trong hệ thống. joblib cần phải được cài đặt mặc dù. Thông tin thêm về joblib có thể được tìm thấy ở đây https://pythonhosted.org/joblib/abul.html
Ngoài ra, bạn có thể sử dụng gói numexpr của python. Nó có rất nhiều chức năng đơn giản hữu ích để lấy thông tin về cpu hệ thống.
import numexpr as ne
print ne.detect_number_of_cores()
Một tùy chọn khác nếu bạn không có Python 2.6:
import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
/proc/<PID>/status
có một số dòng cho bạn biết số lượng CPU trong cpuset hiện tại: tìm kiếmCpus_allowed_list
.