为了账号安全,请及时绑定邮箱和手机立即绑定

听说你只知内存,而不知缓存?CPU表示很伤心!

标签:
架构 运维

一般我们的开发同学们都知道自己机器的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然后放到各级缓存里存起来。请大家牢牢记住这个概念,以后的文章中我们会用到。


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消