查看CPU/CACHE的拓扑结构
转自 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
echo "${cpu##*/}: [Package #$(cat $cpu/topology/physical_package_id), Core #$(cat $cpu/topology/core_id)]"
if ! unshared $cpu/topology/core_siblings_list; then
echo " same package as $(cat $cpu/topology/core_siblings_list)"
fi
if ! unshared $cpu/topology/thread_siblings_list; then
echo " same core as $(cat $cpu/topology/thread_siblings_list)"
fi
for cache in $cpu/cache/index*; do
printf " %-15s " "L$(cat $cache/level) $(cat $cache/type):"
echo "$(cat $cache/size) $(cat $cache/ways_of_associativity)-way with $(cat $cache/coherency_line_size) byte lines"
if ! unshared $cache/shared_cpu_list; then
printf " %-15s [%s]\n" "" "shared with $(cat $cache/shared_cpu_list)"
fi
done
echo
done
|
另一个时候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 软件包中。