15

I have executed the following query:

free -m

And output of this command is:

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

I want to get the size of the CPU cache. Is it possible to get the size of the cache and also what is the use of the cache here?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Naveen Kumar Mishra
  • 321
  • 1
  • 3
  • 16
  • Are you speaking about CPU cache memory or page cache size (which is shown as last column of `free` output)? – myaut May 13 '15 at 09:21

4 Answers4

29

getconf

getconf -a | grep CACHE

gives:

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

Or for a single level:

getconf LEVEL2_CACHE_SIZE

The cool thing about this interface is that it is just a wrapper around the POSIX sysconf C function (cache arguments are non-POSIX extensions), and so it can be used from C code as well:

long l2 = sysconf(_SC_LEVEL2_CACHE_SIZE);

Tested on Ubuntu 16.04 (Xenial Xerus).

x86 CPUID instruction

The CPUID x86 instruction also offers cache information, and can be directly accessed by userland.

glibc seems to use that method for x86. I haven't confirmed by step debugging / instruction tracing, but the source for 2.28 sysdeps/x86/cacheinfo.c does that:

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

TODO: Create a minimal C example, lazy now, asked at: How to receive L1, L2 & L3 cache size using CPUID instruction in x86

ARM also has an architecture-defined mechanism to find cache sizes through registers such as the Cache Size ID Register (CCSIDR), see the ARMv8 Programmers' Manual 11.6 "Cache discovery" for an overview.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
28

If you want to get the size of the CPU caches in Linux, the easiest way to do that is lscpu:

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

If you want to get detailed information on each cache, check the sysfs file system:

$ 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

Some cache instances will be seen multiple times (per each hardware thread), but you can check that in the shared_cpu_list field.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
myaut
  • 11,174
  • 2
  • 30
  • 62
2

For ARM CPUs running Linux (tested on Raspberry Pi 3B+ with Raspbian (32 bit)):

In the "Arm® Cortex®-A53 MPCore Processor Technical Reference Manual" is a chapter, "Cache Size Selection Register" and "Cache Size ID Register", including assembler instructions.

These assembler instructions are already available as functions in the Linux kernel headers asm/cachetype.h: set_csselr(...) and read_ccsidr(), but these function can not be called in user mode, so we need to build a kernel module to get/print the values:

Makefile:

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

File 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);

then:

make
insmode cachesize.ko
rmmod cachesize
dmesg | tail
# Compare numbers to the table "CCSIDR encodings" in the "ARM ... Technical Reference Manual"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
hmmmm
  • 31
  • 3
  • Welcome to Stack Overflow. Code-only answers are discouraged on Stack Overflow because they don't explain how it solves the problem. Please edit your answer to explain what this code does and how it answers the question, so that it is useful to the OP as well as other users with similar issues. – FluffyKitten Aug 18 '20 at 19:22
-1

In my virtual machine (Linux dhcppc4 2.6.32-71.el6.i686 #1 SMP Wed Sep 1 01:26:34 EDT 2010 i686 i686 i386 GNU/Linux), I couldn't find /sys/devices/system/node, but lscpu certainly gives the details.

I see some more information in /sys/devices/system/cpu/cpu0/cache/*:

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

Output

32K

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Surajit
  • 21
  • 4