文章目录
- 1 简介
- 2 工作机制
- 3 Cache Line
参考资料:
1.
https://www.makeuseof.com/tag/what-is-cpu-cache/
2.
https://zhuanlan.zhihu.com/p/80672073
3.CPU Cache 机制以及 Cache miss
4.性能优化方法和技巧
在日常的嵌入式开发中,查看一些SOC的datasheet总会看到 “32KB I/D cache”“L1 cache”“L2 cache”等字样,但是不知道是什么意思,查询了一些资料,记录一下。
1 简介
CPU的运算是需要数据的,因此就需要从内存中读写一些数据来进行运算。但是CPU的运算速度很快,而内存的读写速率相比较于CPU的运行速率就比较慢,因此CPU就需要花费时间等待内存的数据到来或者把数据写入内存,这种操作就无法发挥CPU的全部功力。
因此,一种新的读写速度更快的内存—“缓存”被设计出来,用来存储一些需要频繁被访问的数据,这样CPU会先从速度更快的缓存中来读写数据,加快CPU的运算。
缓存本质上还是内存,只不过读写速度会比内存快很多。
缓存又分为一级缓存L1、二级缓存L2、三级缓存L3:
L1容量最小,但是速度最快,L1又针对指令和数据分为数据缓存和指令缓存;
L2容量比L1大,但是速度会比L1慢些;
L3容量比L2大,速度也相应比L2慢。
每一个核单独有自己的L1和L2,L3属于所有核共享的。
关于访问速度,查询资料,大致如下:
CPU访问一次L1,大约需要4个时钟周期;
CPU访问一次L2,大约需要11个时钟周期;
CPU访问一次L3,大约需要39个时钟周期;
CPU访问一次内存,大约需要107个时钟周期;
从上可以看出,加入了缓存机制,大大提高了CPU的工作效率,防止CPU摸鱼。
在linux下可通过如下指令查看缓存的大小:
# 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 4
LEVEL2_CACHE_LINESIZE 64
LEVEL3_CACHE_SIZE 12582912
LEVEL3_CACHE_ASSOC 16
LEVEL3_CACHE_LINESIZE 64
LEVEL4_CACHE_SIZE 0
LEVEL4_CACHE_ASSOC 0
LEVEL4_CACHE_LINESIZE 0
2 工作机制
缓存的工作机制是比较复杂的,在这里简单的描述下。
当程序执行时,会将内存中的数据载入到L3中,然后再载入L2,最后再载入L1。如果CPU需要数据,则先会在L1中寻找,然后依次是L2、L3、内存中寻找。
如果在L1中找到需要的数据,就叫做“缓存命中”。
当在L1/L2/L3中没有找到数据后,会从内存中读取数据到CPU,并会将这些数据写入到缓存中,防止后续CPU会再次使用,而不需要从内存中读取。
因为缓存的大小是有限的,而CPU会不断执行不同任务,或者CPU需要不同的数据,因此缓存中的数据会按照算法进行替换,将一些不再需要的数据淘汰出缓存,将一些频繁需要的数据放进缓存。
3 Cache Line
CPU将数据加载进缓存中,不会按照一个字节一个字节的方式进行加载,一般按照固定大小的块的进行加载,叫做缓存行即“Cache Line”。
在我的电脑中的Cache Line的大小为64Bytes。
# cat /sys/devices/system/cpu/cpu0/cache/index1/coherency_line_size
64
也可通过指令
# getconf -a | grep CACHE_LINESIZE
LEVEL1_ICACHE_LINESIZE 64
LEVEL1_DCACHE_LINESIZE 64
LEVEL2_CACHE_LINESIZE 64
LEVEL3_CACHE_LINESIZE 64
LEVEL4_CACHE_LINESIZE 0
关于缓存的加载策略,可参考上面链接2,本文只是简单介绍下缓存相关的内容,使对缓存有大致的了解。