转自 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。
1234567891011121314151617181920212223 | #!/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 echodone |
另一个时候cpu_layout.py脚本,来自dpdk项目,用于展示CPU的拓扑结构(不包括cache的信息):http://dpdk.org/browse/dpdk/tree/usertools/cpu_layout.py
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 | #!/usr/bin/env python ## BSD LICENSE (此处省略过多的License信息) from __future__ import print_functionimport systry: xrange # Python 2except 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命令来安装该工具)。
123456789101112 | [root@jay-linux ~]$ numactl –hardwareavailable: 2 nodes (0-1)node 0 cpus: 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23node 0 size: 64395 MBnode 0 free: 62846 MBnode 1 cpus: 8 9 10 11 12 13 14 15 24 25 26 27 28 29 30 31node 1 size: 64507 MBnode 1 free: 63676 MBnode distances:node 0 1 0: 10 20 1: 20 10 |
另外,lscpu 命令也是可以查看很多CPU的信息(包括:架构、逻辑CPU数量、核数、主频、Cache大小、NUMA信息等),该命令在CentOS上是在 util-linux 软件包中。