个别咱们的开发同学们都晓得本人机器的 CPU 是几核、内存是多大。然而对于 CPU 外部对程序性能影响较大的缓存却是只知其一; 不知其二。有些开发同学都是计算机的缓存有 L1、L2、L3,然而再具体一点的问题,可能就很少有同学能答的残缺了。如果上面这几个问题你能脱口而出,请跳过本节。例如:
- 缓存到底在哪里?
- L1 有几种?
- 你的缓存有几级,别离是多大?
- 你的 24 核的机器,一二三级缓存别离有几个,存在共享的状况吗?
其实缓存对计算机程序运行性能影响极大,然而他们在开发同学心目中的存在感却不如内存高。要晓得 CPU 缓存以及缓存算法的设计是古代 CPU 设计的外围工作之一。飞哥感觉缓存们肯定感到很伤心。
Intel CPU 体系结构
其实在 286 之前的时代的 CPU 本是没有缓存的,因为过后的 CPU 和内存速度差别没有当初这么大,CPU 间接拜访内存。然而到 386 时代,CPU 和内存的速度不匹配了,第一次呈现了缓存。而且最早的缓存并没有放在 CPU 模块里,而是放在主板上的。再往后 CPU 越来越快,当初 CPU 的速度比内存要快百倍以上,所以就逐渐演化出了 L1、L2、L3 三级缓存构造,而且都集成到的 CPU 芯片里,以进一步提高访问速度。
咱们来看下古代 Intel 的 CPU 架构的根本构造。
L1 最靠近于 CPU,速度也最快,然而容量最小。个别古代 CPU 的 L1 会分成两个,一个用来 cache data,一个用来 cache code,这是因为 code 和 data 的更新策略并不相同,而且因为 CISC 的变长指令,code cache 要做非凡优化。个别每个核都有本人独立的 data L1 和 code L1。
越往下,速度越慢,容量越大。L2 个别也能够做到每个核一个独立的。然而 L3 个别就是整颗 CPU 共享的了。
UEFIBlog 里提供了一个比拟好的物理解剖图,比拟好地展现了进去:
理论查看
下面介绍的只是抽象的概念。然而每个 CPU 的缓存都是不一样的,而且“纸上得来终觉浅”,我感觉咱们还是有必要进行下一步的实机勘探工作。
Linux 的内核的开发者定义了一套框架模型来实现这一目标,它就是 CPUFreq 零碎。
CPUFreq 提供的 sysfs 接口,能够让咱们看到比 /proc/cpuinfo 更为具体的 CPU 详细信息。
# cd /sys/devices/system/cpu/;ll
drwxr-xr-x 7 root root 0 Apr 15 15:29 cpu0
drwxr-xr-x 7 root root 0 Apr 15 15:29 cpu1
......
- L1 一级缓存查看:
# cat cpu0/cache/index0/level
1
# cat cpu0/cache/index0/size
32K
# cat cpu0/cache/index0/type
Data
# cat cpu0/cache/index0/shared_cpu_list
0,12
# cat cpu0/cache/index1/level
1
# cat cpu0/cache/index1/size
32K
# cat cpu0/cache/index1/type
Instruction
# cat cpu0/cache/index1/shared_cpu_list
0,12
从下面的 level 接口能够看出 index0 和 index1 都是一级缓存,只不过一个是 Data 数据缓存,一个是 Instruction 也就是代码缓存。
等等,下面提到的是每个 Core 是独立的 L1 缓存,为什么 shared_cpu_list 显示有共享?对了咱们这里看到的 cpu0 并不是物理 Core,而是逻辑核,都是超线程技术虚构进去的。实际上 cpu0 和 cpu12 是属于一个物理 Core,所以每个 Data L1 和 Instruction 是这两个逻辑核共享的。
我的这台电脑里,总共是有 12 个 Data L1,12 个 Instrunction L1,大小都是 32K。
- L2 二级缓存查看:
# cat cpu0/cache/index2/size
256K
# cat cpu0/cache/index2/type
Unified
# cat cpu0/cache/index2/shared_cpu_list
0,12
二级缓存要比一级缓存大不少,有 256K,然而不分 Data 和 Instruction。另外 L2 和 L1 一样,也是总共有 12 个,每两个逻辑核共享一个 L2。
- L3 三级缓存查看:
# cat cpu0/cache/index3/size
12288K
# cat cpu0/cache/index3/type
Unified
# cat cpu0/cache/index3/shared_cpu_list
0-5,12-17
#cat cpu6/cache/index3/shared_cpu_list
6-11,18-23
L3 达到了 12M,你去买 CPU 的时候商品里能看到的缓存属性个别通知你的就是这个 L3 属性。因为 L3 要比 L2 和 L1 看起来要大的多,能激发你购买的欲望。但实际上我的这台电脑里 L3 只有两个,每个 CPU 各一个,不像是 L2、L1 有很多。第 0 -5,12-17 号逻辑核共享一个 L3,因为它们是在一个物理 CPU 上。6-11,18-23 共享另一个。
另外,Linux 上还有个 dmidecode 命令,也能查看到一些对于 CPU 缓存的信息,感兴趣的小伙伴们能够试试
# dmidecode -t cache
可能有的同学会问了,我用的操作系统是 windows 啊,怎么看?关上 cmd 命令行,输出以下命令试试吧,飞哥在 windows 上晓得的就这么多了,感兴趣的话你本人 google 上搜搜吧。
# wmic cpu get L2CacheSize,L3CacheSize
扩大常识
Cache Line: 咱们后面只介绍了各个级别的缓存,然而这外面有个很重要的概念就是 Cache Line,就是本级缓存向下一层取数据时的根本单位。能够通过如下形式查看:
# cd /sys/devices/system/cpu/;ll
# cat cpu0/cache/index0/coherency_line_size
64
# cat cpu0/cache/index1/coherency_line_size
64
# cat cpu0/cache/index2/coherency_line_size
64
# cat cpu0/cache/index3/coherency_line_size
64
能够看到 L1、L2、L3 的 Cache Line 大小都是 64 字节(留神是字节)。就是说每次 cpu 从内存获取数据的时候,都是以该单位来进行的,哪怕你只取一个 bit,CPU 也是给你取一个 Cache Line 而后放到各级缓存里存起来。请大家牢牢记住这个概念,当前的文章中咱们会用到。
开发内功修炼之 CPU 篇专辑:
- 1. 你认为你的多核 CPU 都是真核吗?多核“假象”
- 2. 据说你只知内存,而不知缓存?CPU 示意很伤心!
- 3.TLB 缓存是个神马鬼,如何查看 TLB miss?
- 4. 过程 / 线程切换到底须要多少开销?
- 5. 协程到底比线程牛在什么中央?
- 6. 软中断会吃掉你多少 CPU?
- 7. 一次零碎调用开销到底有多大?
- 8. 一次简略的 php 申请 redis 会有哪些开销?
- 9. 函数调用太多了会有性能问题吗?
我的公众号是「开发内功修炼」,在这里我不是单纯介绍技术实践,也不只介绍实践经验。而是把实践与实际联合起来,用实际加深对实践的了解、用实践进步你的技术实际能力。欢送你来关注我的公众号,也请分享给你的好友~~~