[英]How to find out the number of CPUs using python
我想知道使用 Python 的本地計算機上的 CPU 數量。當使用優化擴展的僅限用戶空間的程序調用時,結果應該是user/real
as output by time(1)
。
如果你有 python 版本 >= 2.6 你可以簡單地使用
import multiprocessing
multiprocessing.cpu_count()
http://docs.python.org/library/multiprocessing.html#multiprocessing.cpu_count
如果您對當前進程可用的處理器數量感興趣,則必須先檢查cpuset 。 否則(或者如果 cpuset 未被使用), multiprocessing.cpu_count()
是 Python 2.6 和更新版本中 go 的方法。 以下方法回退到舊版本 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')
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
表示獲取當前進程的值。 function 返回一set()
允許的 CPU,因此需要len()
。
另一方面, multiprocessing.cpu_count()
和os.cpu_count()
只返回物理 CPU 的總數。
差異尤為重要,因為某些集群管理系統(例如Platform LSF )使用sched_getaffinity
限制作業 CPU 使用率。
因此,如果您使用multiprocessing.cpu_count()
,您的腳本可能會嘗試使用比它可用的更多的內核,這可能會導致過載和超時。
我們可以通過使用taskset
實用程序限制親和力來具體地看到差異,這使我們能夠控制進程的親和力。
最小taskset
示例
例如,如果我在 16 核系統中將 Python 限制為僅 1 個核(核 0):
taskset -c 0 ./main.py
使用測試腳本:
主程序
#!/usr/bin/env python3
import multiprocessing
import os
print(multiprocessing.cpu_count())
print(os.cpu_count())
print(len(os.sched_getaffinity(0)))
那么 output 是:
16
16
1
與nproc
默認情況下, nproc
確實尊重親和力,並且:
taskset -c 0 nproc
輸出:
1
man nproc
使這一點非常明確:
打印可用的處理單元數
因此,默認情況下len(os.sched_getaffinity(0))
的行為類似於nproc
。
nproc
有--all
標志,用於不太常見的情況,您希望在不考慮任務集的情況下獲取物理 CPU 計數:
taskset -c 0 nproc --all
os.cpu_count
文檔
os.cpu_count
的文檔也簡單提到了這個https://docs.python.org/3.8/library/os.html#os.cpu_count
此數量不等於當前進程可以使用的 CPU 數量。 可以使用
len(os.sched_getaffinity(0))
獲得可用 CPU 的數量
在multiprocessing.cpu_count
的文檔中也復制了相同的評論: https://docs.python.org/3/library/multiprocessing.html#multiprocessing.cpu_count
從Lib/multiprocessing/context.py
下的 3.8 源代碼我們還看到multiprocessing.cpu_count
只是轉發到os.cpu_count
,除了multiprocessing
拋出異常而不是在os.cpu_count
失敗時返回 None :
def cpu_count(self):
'''Returns the number of CPUs in the system'''
num = os.cpu_count()
if num is None:
raise NotImplementedError('cannot determine number of cpus')
else:
return num
3.8 可用性:具有本機sched_getaffinity
的系統 function
這個os.sched_getaffinity
的唯一缺點是,從 Python 3.8 開始,這似乎是 UNIX。
cpython 3.8 似乎只是嘗試在配置期間使用sched_setaffinity
function 調用編譯一個小的 C hello world,如果不存在,則HAVE_SCHED_SETAFFINITY
未設置並且 function 可能會丟失:
psutil.Process().cpu_affinity()
:帶有 Windows 端口的第三方版本
第三方psutil
package ( pip install psutil
) 已在以下位置提及: https://stackoverflow.com/a/14840102/895245但不是cpu_affinity
function :8810568383ps5270 psutil.Process.cpu_affinity
用法:
import psutil
print(len(psutil.Process().cpu_affinity()))
這個 function 與 Linux 上的標准庫os.sched_getaffinity
的功能相同,但他們還通過調用GetProcessAffinityMask
Windows API 8834800840888 實現了它
所以換句話說:那些 Windows 用戶必須停止偷懶並向上游 stdlib 發送補丁:-)
在 Ubuntu 16.04、Python 3.5.2 中測試。
另一種選擇是使用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()
是根據此 function 實現的,但如果os.cpu_count()
返回None
(“無法確定 CPU 的數量”),則會引發NotImplementedError
。
如果您想知道物理內核(不是虛擬超線程內核)的數量,這里有一個獨立於平台的解決方案:
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
關鍵字參數。
import os
print(os.cpu_count())
這些為您提供超線程 CPU 計數
multiprocessing.cpu_count()
os.cpu_count()
這些為您提供虛擬機 CPU 計數
psutil.cpu_count()
numexpr.detect_number_of_cores()
僅當您在 VM 上工作時才重要。
對於 python 版本 3.4 以上你可以使用
import os
os.cpu_count()
如果您正在尋找 linux 命令nproc
的等價物。 你有這個選擇
len(os.sched_getaffinity(0))
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 旨在跨操作系統和體系結構移植。
這可能適用於我們這些使用不同操作系統/系統但希望獲得最佳效果的人:
import os
workers = os.cpu_count()
if 'sched_getaffinity' in dir(os):
workers = len(os.sched_getaffinity(0))
您也可以為此目的使用“joblib”。
import joblib
print joblib.cpu_count()
此方法將為您提供系統中的 CPU 數量。 不過需要安裝 joblib。 有關 joblib 的更多信息,請參見此處https://pythonhosted.org/joblib/parallel.html
或者,您可以使用 python 的 numexpr package。它有很多簡單的函數,有助於獲取有關系統 cpu 的信息。
import numexpr as ne
print ne.detect_number_of_cores()
無法弄清楚如何添加到代碼或回復消息,但這里有對 jython 的支持,您可以在放棄之前加入:
# jython
try:
from java.lang import Runtime
runtime = Runtime.getRuntime()
res = runtime.availableProcessors()
if res > 0:
return res
except ImportError:
pass
如果您使用的是手電筒,您可以執行以下操作:
import torch.multiprocessing as mp
mp.cpu_count()
火炬中的 mp 庫與主要的 python 庫具有相同的界面,因此您也可以像評論者提到的那樣執行此操作:
python -c "import multiprocessing; print(multiprocessing.cpu_count())"
希望這可以幫助; .) 有多個選項總是好的。
如果您沒有 Python 2.6,則另一種選擇:
import commands
n = commands.getoutput("grep -c processor /proc/cpuinfo")
如果您要打印系統中的核心數。
試試這個:
import os
no_of_cores = os.cpu_count()
print(no_of_cores)
這應該有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.