檢視CPU/CACHE的拓撲結構
阿新 • • 發佈:2018-11-27
轉自 http://smilejay.com/2017/12/cpu-cache-topology/
Linux上,CPU和Cache相關的拓撲結構,都可以從sysfs檔案系統的目錄 /sys/devices/system/cpu/ 來獲取詳細資訊。
在網上,找了對CPU相關拓撲結構的解析的兩個指令碼,覺得還不錯;儘管看起來仍有些粗糙,也暫時去改進了。
一個是來自:https://gist.github.com/stedolan/1089968 ; 它可以打印出每個邏輯CPU屬於那兒Socket、哪個core,以及與哪些CPU共享L1/L2/L3的Cache。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#!/bin/bash
unshared () {
grep '^[0-9]\+$' "$1" > /dev/null
}
for cpu in $(ls -d /sys/devices/system/cpu/cpu[0-9]* | sort -t u -k 3 -n); do |
另一個時候cpu_layout.py指令碼,來自dpdk專案,用於展示CPU的拓撲結構(不包括cache的資訊):http://dpdk.org/browse/dpdk/tree/usertools/cpu_layout.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | #!/usr/bin/env python # # BSD LICENSE (此處省略過多的License資訊) from __future__ import print_function import sys try: xrange # Python 2 except NameError: xrange = range # Python 3 sockets = [] cores = [] core_map = {} base_path = "/sys/devices/system/cpu" fd = open("{}/kernel_max".format(base_path)) max_cpus = int(fd.read()) fd.close() for cpu in xrange(max_cpus + 1): try: fd = open("{}/cpu{}/topology/core_id".format(base_path, cpu)) except IOError: continue except: break core = int(fd.read()) fd.close() fd = open("{}/cpu{}/topology/physical_package_id".format(base_path, cpu)) socket = int(fd.read()) fd.close() if core not in cores: cores.append(core) if socket not in sockets: sockets.append(socket) key = (socket, core) if key not in core_map: core_map[key] = [] core_map[key].append(cpu) print(format("=" * (47 + len(base_path)))) print("Core and Socket Information (as reported by '{}')".format(base_path)) print("{}\n".format("=" * (47 + len(base_path)))) print("cores = ", cores) print("sockets = ", sockets) print("") max_processor_len = len(str(len(cores) * len(sockets) * 2 - 1)) max_thread_count = len(list(core_map.values())[0]) max_core_map_len = (max_processor_len * max_thread_count) \ + len(", ") * (max_thread_count - 1) \ + len('[]') + len('Socket ') max_core_id_len = len(str(max(cores))) output = " ".ljust(max_core_id_len + len('Core ')) for s in sockets: output += " Socket %s" % str(s).ljust(max_core_map_len - len('Socket ')) print(output) output = " ".ljust(max_core_id_len + len('Core ')) for s in sockets: output += " --------".ljust(max_core_map_len) output += " " print(output) for c in cores: output = "Core %s" % str(c).ljust(max_core_id_len) for s in sockets: if (s,c) in core_map: output += " " + str(core_map[(s, c)]).ljust(max_core_map_len) else: output += " " * (max_core_map_len + 1) print(output) |
當NUMA架構下,你可能還需要了解NUMA的分佈,包括每個節點上有哪些邏輯處理器、有多少記憶體等資訊,那麼使用numactl工具來檢視(在CentOS上可以用yum install numactl命令來安裝該工具)。
1 2 3 4 5 6 7 8 9 10 11 12 | [root@jay-linux ~]$ numactl --hardware available: 2 nodes (0-1) node 0 cpus: 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23 node 0 size: 64395 MB node 0 free: 62846 MB node 1 cpus: 8 9 10 11 12 13 14 15 24 25 26 27 28 29 30 31 node 1 size: 64507 MB node 1 free: 63676 MB node distances: node 0 1 0: 10 20 1: 20 10 |
另外,lscpu 命令也是可以檢視很多CPU的資訊(包括:架構、邏輯CPU數量、核數、主頻、Cache大小、NUMA資訊等),該命令在CentOS上是在 util-linux 軟體包中。