以编程方式获取关于 Linux 的准确 CPU 缓存层次结构信息
Programmatically get accurate CPU cache hierarchy information on Linux
我正在尝试获取 Linux 上当前 CPU 的数据缓存层次结构的准确描述:不仅仅是单个 L1/L2/L3 的大小(可能还有 L4)数据缓存,以及它们在核心之间拆分或共享的方式。
例如,在我的 CPU (AMD Ryzen Threadripper 3970X) 上,每个核心都有自己的 32 KB 一级数据缓存和 512 KB 二级缓存,但是三级缓存在一个内核之间共享核心复合体 (CCX)。换句话说,有 8 个不同的 L3 缓存,每个 16 MB。
CPU-Z 在 Windows 上的屏幕截图的 "Cache" 部分基本上是我想要找出的内容:
我使用 GetLogicalProcessorInformation()
在 Windows 上获取这些信息没问题。
但是,在 Linux 上,sysconf()
似乎只提供了 L1 和 L2 数据缓存的每核心缓存大小(_SC_LEVEL1_DCACHE_SIZE
和 _SC_LEVEL2_DCACHE_SIZE
),或总的 L3 缓存大小 (_SC_LEVEL3_CACHE_SIZE
)。
编辑:lstopo 在 VMWare 下的输出 。虚拟机有 8 个核心。 L1 和 L2 缓存信息很好,但 L3 缓存大小似乎不正确:
可以通过在 /sys
(sysfs) 中打开文件以编程方式找到缓存层次结构的全貌。
每个 "thread" 或 "logical processor" 由 /sys/devices/system/cpu/
中的子目录表示。在该目录中,您将找到一个缓存目录。例如,第一个逻辑处理器的缓存信息可以在这里找到:
$ ls /sys/devices/system/cpu/cpu0/cache/
index0
index1
index2
index3
power
uevent
与该逻辑处理器关联的每个缓存实体都由一个 index[0-9]*
目录表示。指数后的数字不代表等级。同一个缓存实体可能在不同的逻辑处理器下被多次列出。在这些目录中,您可以找到缓存实体的所有属性(级别、集合、行大小等)。
$ ls /sys/devices/system/cpu/cpu0/cache/index0
coherency_line_size
level
number_of_sets
physical_line_partition
power
shared_cpu_list
shared_cpu_map
size
type
uevent
ways_of_associativity
可以找到完整的文档 here。
最重要的是,要获得所需的输出,您需要检查 shared_cpu_list
:
$ cat /sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_list
0,28
这将向您显示哪些逻辑处理器共享此缓存实体。通过检查所有实体 (/sys/devices/system/cpu/cpu*/cache/index*/
) 并使用 shared_cpu_list
消除重复项,您可以以编程方式访问所需的所有数据。
请注意,您的管理程序不需要传递准确的信息。这只会向您显示来宾内核看到的缓存层次结构。
我正在尝试获取 Linux 上当前 CPU 的数据缓存层次结构的准确描述:不仅仅是单个 L1/L2/L3 的大小(可能还有 L4)数据缓存,以及它们在核心之间拆分或共享的方式。
例如,在我的 CPU (AMD Ryzen Threadripper 3970X) 上,每个核心都有自己的 32 KB 一级数据缓存和 512 KB 二级缓存,但是三级缓存在一个内核之间共享核心复合体 (CCX)。换句话说,有 8 个不同的 L3 缓存,每个 16 MB。
CPU-Z 在 Windows 上的屏幕截图的 "Cache" 部分基本上是我想要找出的内容:
我使用 GetLogicalProcessorInformation()
在 Windows 上获取这些信息没问题。
但是,在 Linux 上,sysconf()
似乎只提供了 L1 和 L2 数据缓存的每核心缓存大小(_SC_LEVEL1_DCACHE_SIZE
和 _SC_LEVEL2_DCACHE_SIZE
),或总的 L3 缓存大小 (_SC_LEVEL3_CACHE_SIZE
)。
编辑:lstopo 在 VMWare 下的输出 。虚拟机有 8 个核心。 L1 和 L2 缓存信息很好,但 L3 缓存大小似乎不正确:
可以通过在 /sys
(sysfs) 中打开文件以编程方式找到缓存层次结构的全貌。
每个 "thread" 或 "logical processor" 由 /sys/devices/system/cpu/
中的子目录表示。在该目录中,您将找到一个缓存目录。例如,第一个逻辑处理器的缓存信息可以在这里找到:
$ ls /sys/devices/system/cpu/cpu0/cache/
index0
index1
index2
index3
power
uevent
与该逻辑处理器关联的每个缓存实体都由一个 index[0-9]*
目录表示。指数后的数字不代表等级。同一个缓存实体可能在不同的逻辑处理器下被多次列出。在这些目录中,您可以找到缓存实体的所有属性(级别、集合、行大小等)。
$ ls /sys/devices/system/cpu/cpu0/cache/index0
coherency_line_size
level
number_of_sets
physical_line_partition
power
shared_cpu_list
shared_cpu_map
size
type
uevent
ways_of_associativity
可以找到完整的文档 here。
最重要的是,要获得所需的输出,您需要检查 shared_cpu_list
:
$ cat /sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_list
0,28
这将向您显示哪些逻辑处理器共享此缓存实体。通过检查所有实体 (/sys/devices/system/cpu/cpu*/cache/index*/
) 并使用 shared_cpu_list
消除重复项,您可以以编程方式访问所需的所有数据。
请注意,您的管理程序不需要传递准确的信息。这只会向您显示来宾内核看到的缓存层次结构。