个别咱们的开发同学们都晓得本人机器的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.函数调用太多了会有性能问题吗?
我的公众号是「开发内功修炼」,在这里我不是单纯介绍技术实践,也不只介绍实践经验。而是把实践与实际联合起来,用实际加深对实践的了解、用实践进步你的技术实际能力。欢送你来关注我的公众号,也请分享给你的好友~~~