c++ - 在 Linux 上以编程方式获取准确的 CPU 缓存层次结构信息

标签 c++ c linux cpu-architecture cpu-cache

我正在尝试准确描述 Linux 上当前 CPU 的数据缓存层次结构:不仅是单个 L1/L2/L3(可能还有 L4)数据缓存的大小,还有它们拆分或共享的方式核心。

例如,在我的 CPU(AMD Ryzen Threadripper 3970X)上,每个内核都有自己的 32 KB 的 L1 数据缓存和 512 KB 的 L2 缓存,但是 L3 缓存在一个核心复合体 (CCX) 内的内核之间共享。换句话说,有 8 个不同的 L3 缓存,每个 16 MB。

Windows 上 CPU-Z 的此屏幕截图的“缓存”部分基本上是我试图找出的内容:

CPU-Z Screenshot

我可以通过 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 缓存大小似乎不正确:

lstopo Screenshot

最佳答案

可以通过在 /sys 中打开文件以编程方式找到缓存层次结构的完整图片。 (系统文件)。

每个“线程”或“逻辑处理器”由 /sys/devices/system/cpu/ 中的子目录表示。 .在该目录中,您将找到一个缓存目录。例如,可以在此处找到第一个逻辑处理器的缓存信息:

$ ls /sys/devices/system/cpu/cpu0/cache/
index0
index1
index2
index3
power
uevent

与该逻辑处理器关联的每个缓存实体由 index[0-9]* 表示。目录。 index后面的数字不代表级别。相同的缓存实体可能会在不同的逻辑处理器下多次列出。在这些目录中,您可以找到缓存实体的所有属性(级别、集、行大小等)。
$ 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 消除重复项,您可以以编程方式访问您需要的所有数据。

请注意,您的管理程序不需要传递准确的信息。这只会向您显示 guest 内核看到的缓存层次结构。

关于c++ - 在 Linux 上以编程方式获取准确的 CPU 缓存层次结构信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61454437/

相关文章:

linux - Debian 服务器崩溃后 uWSGI 突然无法再次启动

c++ - 为什么相同大小的函数参数中的隐式转换不会引发警告?

c++ - 多个默认构造函数

c - 预期在 '{' token 之前出现非限定 ID,预期在 "main"之前出现初始值设定项

c++ - 调试 CUDA 代码

linux - 在 Bash 脚本中将单词定义为变量

c++ - QuickFix C++ 和 SSL : Issue connecting to LMAX using sTunnel

c++ - 如何将wstring转换为字节 vector

c - 在 C 中使用八进制转义序列

linux - Ant、sudo 和 copy 不工作