【问题标题】:How to get the size of the CPU cache in Linux如何在 Linux 中获取 CPU 缓存的大小
【发布时间】:2015-05-13 06:31:52
【问题描述】:

我已经执行了以下查询:

free -m

这个命令的输出是:

           total       used       free     shared    buffers     cached
Mem:        2048       2018         29          5          0       595

我想获取 CPU 缓存的大小。是否可以获取缓存的大小以及这里的缓存有什么用?

【问题讨论】:

  • 你说的是CPU缓存内存还是页面缓存大小(显示为free输出的最后一列)?

标签: linux linux-kernel centos


【解决方案1】:

如果你想获取 Linux 中 CPU 缓存的大小,最简单的方法是lscpu

$ lscpu | grep cache
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              15360K

如果您想获取每个缓存的详细信息,请查看sysfs 文件系统:

$ SYSNODE=/sys/devices/system/node
$ grep '.*' $SYSNODE/node*/cpu*/cache/index*/* 2>/dev/null | 
    awk '-F[:/]' '{ printf "%6s %6s %24s %s\n" $6, $7, $9, $10, $11 ; }'
node0  cpu0 index0                    level 1
node0  cpu0 index0           number_of_sets 64
node0  cpu0 index0  physical_line_partition 1
node0  cpu0 index0          shared_cpu_list 0,12
node0  cpu0 index0           shared_cpu_map 0000,00001001
node0  cpu0 index0                     size 32K
node0  cpu0 index0                     type Data
node0  cpu0 index0    ways_of_associativity 8
node0  cpu0 index1      coherency_line_size 64

某些缓存实例会被多次看到(每个硬件线程),但您可以在 shared_cpu_list 字段中查看。

【讨论】:

    【解决方案2】:

    getconf

    getconf -a | grep CACHE
    

    给予:

    LEVEL1_ICACHE_SIZE                 32768
    LEVEL1_ICACHE_ASSOC                8
    LEVEL1_ICACHE_LINESIZE             64
    LEVEL1_DCACHE_SIZE                 32768
    LEVEL1_DCACHE_ASSOC                8
    LEVEL1_DCACHE_LINESIZE             64
    LEVEL2_CACHE_SIZE                  262144
    LEVEL2_CACHE_ASSOC                 8
    LEVEL2_CACHE_LINESIZE              64
    LEVEL3_CACHE_SIZE                  20971520
    LEVEL3_CACHE_ASSOC                 20
    LEVEL3_CACHE_LINESIZE              64
    LEVEL4_CACHE_SIZE                  0
    LEVEL4_CACHE_ASSOC                 0
    LEVEL4_CACHE_LINESIZE              0
    

    或单层:

    getconf LEVEL2_CACHE_SIZE
    

    这个接口很酷的地方在于它只是 POSIX sysconf C 函数的包装器(缓存参数是非 POSIX 扩展),因此它也可以在 C 代码中使用:

    long l2 = sysconf(_SC_LEVEL2_CACHE_SIZE);
    

    Ubuntu 16.04(Xenial Xerus)上测试。

    x86 CPUID 指令

    CPUIDx86 指令还提供缓存信息,用户态可以直接访问。

    glibc 似乎将该方法用于 x86。我还没有通过逐步调试/指令跟踪确认,但是 2.28 sysdeps/x86/cacheinfo.c 的源代码是这样做的:

    __cpuid (2, eax, ebx, ecx, edx);
    

    TODO:创建一个最小的 C 示例,现在懒惰了,问:How to receive L1, L2 & L3 cache size using CPUID instruction in x86

    ARM 还具有架构定义的机制,可通过缓存大小 ID 寄存器 (CCSIDR) 等寄存器查找缓存大小,请参阅ARMv8 Programmers' Manual 11.6“缓存发现”了解概述。

    【讨论】:

      【解决方案3】:

      对于运行 Linux 的 ARM CPU(在带有 Raspbian(32 位)的 Raspberry Pi 3B+ 上测试):

      《Arm® Cortex®-A53 MPCore处理器技术参考手册》中有一章,“缓存大小选择寄存器”“缓存大小ID寄存器”,包括汇编指令。

      这些汇编指令已经作为函数在 Linux 内核头文件 asm/cachetype.h 中可用:set_csselr(...) 和 read_ccsidr(),但是这些函数不能在用户模式下调用,所以我们需要构建一个内核模块来获取/打印值:

      生成文件:

      obj-m += cachesize.o
      
      all:
      
          make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
      
      clean:
      
          make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
      

      文件cachesize.c

      #include <asm/cachetype.h>
      #include <linux/init.h>
      #include <linux/module.h>
      #include <linux/kernel.h>
      
      MODULE_LICENSE("GPL");
      MODULE_AUTHOR("Abc defg");
      MODULE_DESCRIPTION("Find out ARM cache sizes");
      MODULE_VERSION("0.01");
      
      static int __init lkm_example_init(void) {
      // Must run in kernel mode
      // Assumptions: L1 (instructions + data), L2 (check your CPU manual)
       set_csselr(0);
       printk(KERN_INFO "ccsidr L1 data cache = %08x\n", read_ccsidr());
       set_csselr(1);
       printk(KERN_INFO "ccsidr L1 instruction cache = %08x\n", read_ccsidr());
       set_csselr(2);
       printk(KERN_INFO "ccsidr L2 unified = %08x\n", read_ccsidr());
       return 0;
      }
      
      static void __exit lkm_example_exit(void) {
       printk(KERN_INFO "Goodbye, World!\n");
      }
      
      module_init(lkm_example_init);
      module_exit(lkm_example_exit);
      

      然后:

      make
      insmode cachesize.ko
      rmmod cachesize
      dmesg | tail
      # Compare numbers to the table "CCSIDR encodings" in the "ARM ... Technical Reference Manual"
      

      【讨论】:

      • 欢迎来到 Stack Overflow。 Stack Overflow 上不鼓励仅使用代码的答案,因为它们没有解释它是如何解决问题的。请编辑您的答案以解释此代码的作用以及它如何回答问题,以便它对 OP 以及其他有类似问题的用户有用。
      【解决方案4】:

      在我的虚拟机中(Linux dhcppc4 2.6.32-71.el6.i686 #1 SMP Wed Sep 1 01:26:34 EDT 2010 i686 i686 i386 GNU/Linux),我找不到 /sys /devices/system/node,但 lscpu 肯定会给出详细信息。

      我在/sys/devices/system/cpu/cpu0/cache/*看到了更多信息:

      cat /sys/devices/system/cpu/cpu0/cache/index0/size
      

      输出

      32K

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-21
        • 1970-01-01
        • 2013-05-07
        • 2018-02-05
        • 2017-03-23
        • 2021-11-27
        • 1970-01-01
        • 2013-10-08
        相关资源
        最近更新 更多