转自 查看CPU/CACHE的拓扑结构 - blogsheng - 博客园
Linux上,CPU和Cache相关的拓扑结构,都可以从sysfs文件系统的目录 /sys/devices/system/cpu/ 来获取详细信息。
在网上,找了对CPU相关拓扑结构的解析的两个脚本,觉得还不错;尽管看起来仍有些粗糙,也暂时去改进了。
一个是来自:Prints number of cores, CPU topology and cache topology/size on Linux machines · GitHub ; 它可以打印出每个逻辑CPU属于那儿Socket、哪个core,以及与哪些CPU共享L1/L2/L3的Cache。
#!/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的信息):cpu_layout.py\usertools - dpdk - Data Plane Development Kit
#!/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命令来安装该工具)。
$ numactl --hardware
available: 4 nodes (0-3)
node 0 cpus: 0 1 2 3 7 8 12 13 14 18 19 20 48 49 50 51 55 56 60 61 62 66 67 68
node 0 size: 95207 MB
node 0 free: 38465 MB
node 1 cpus: 4 5 6 9 10 11 15 16 17 21 22 23 52 53 54 57 58 59 63 64 65 69 70 71
node 1 size: 96762 MB
node 1 free: 40779 MB
node 2 cpus: 24 25 26 27 31 32 33 37 38 39 43 44 72 73 74 75 79 80 81 85 86 87 91 92
node 2 size: 96762 MB
node 2 free: 40226 MB
node 3 cpus: 28 29 30 34 35 36 40 41 42 45 46 47 76 77 78 82 83 84 88 89 90 93 94 95
node 3 size: 96222 MB
node 3 free: 41866 MB
node distances:
node 0 1 2 3
0: 10 11 21 21
1: 11 10 21 21
2: 21 21 10 11
3: 21 21 11 10
另外,lscpu 命令也是可以查看很多CPU的信息(包括:架构、逻辑CPU数量、核数、主频、Cache大小、NUMA信息等),该命令在CentOS上是在 util-linux 软件包中。
还有 cat /proc/cpuinfo,分享另一个通过cat /proc/cpuinfo来获取信息的脚本
#!/bin/bash
# Simple print cpu topology
# Author: kodango
function get_nr_processor()
{
grep '^processor' /proc/cpuinfo | wc -l
}
function get_nr_socket()
{
grep 'physical id' /proc/cpuinfo | awk -F: '{
print $2 | "sort -un"}' | wc -l
}
function get_nr_siblings()
{
grep 'siblings' /proc/cpuinfo | awk -F: '{
print $2 | "sort -un"}'
}
function get_nr_cores_of_socket()
{
grep 'cpu cores' /proc/cpuinfo | awk -F: '{
print $2 | "sort -un"}'
}
echo '===== CPU Topology Table ====='
echo
echo '+--------------+---------+-----------+'
echo '| Processor ID | Core ID | Socket ID |'
echo '+--------------+---------+-----------+'
while read line; do
if [ -z "$line" ]; then
printf '| %-12s | %-7s | %-9s |\n' $p_id $c_id $s_id
echo '+--------------+---------+-----------+'
continue
fi
if echo "$line" | grep -q "^processor"; then
p_id=`echo "$line" | awk -F: '{print $2}' | tr -d ' '`
fi
if echo "$line" | grep -q "^core id"; then
c_id=`echo "$line" | awk -F: '{print $2}' | tr -d ' '`
fi
if echo "$line" | grep -q "^physical id"; then
s_id=`echo "$line" | awk -F: '{print $2}' | tr -d ' '`
fi
done < /proc/cpuinfo
echo
awk -F: '{
if ($1 ~ /processor/) {
gsub(/ /,"",$2);
p_id=$2;
} else if ($1 ~ /physical id/){
gsub(/ /,"",$2);
s_id=$2;
arr[s_id]=arr[s_id] " " p_id
}
}
END{
for (i in arr)
printf "Socket %s:%s\n", i, arr[i];
}' /proc/cpuinfo
echo
echo '===== CPU Info Summary ====='
echo
nr_processor=`get_nr_processor`
echo "Logical processors: $nr_processor"
nr_socket=`get_nr_socket`
echo "Physical socket: $nr_socket"
nr_siblings=`get_nr_siblings`
echo "Siblings in one socket: $nr_siblings"
nr_cores=`get_nr_cores_of_socket`
echo "Cores in one socket: $nr_cores"
let nr_cores*=nr_socket
echo "Cores in total: $nr_cores"
if [ "$nr_cores" = "$nr_processor" ]; then
echo "Hyper-Threading: off"
else
echo "Hyper-Threading: on"
fi
echo
echo '===== END ====='
如果想要查看cache共享情况可以通过下面的命令:
cat /sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_list
如查看cpu0 的一级缓存中的有多少组,(cache多路组相连的具体情况)
$ cat /sys/devices/system/cpu/cpu0/cache/index0/number_of_sets
64
如查看cpu0的一级缓存中一组中的行数
$cat /sys/devices/system/cpu/cpu0/cache/index0/ways_of_associativity
8
index3 代表L3 cache,cpu0代表查看和cpu0共享L3 cache的情况,查看其他的cpu修改为对应的值即可。
index0和Index1是一级cache中的data和instruction cache
$ cat /sys/devices/system/cpu/cpu0/cache/index0/type
Data
$ cat /sys/devices/system/cpu/cpu0/cache/index1/type
Instruction
参考链接