CPU基础知识之Cache介绍

一、什么是Cache

Cache就是CPU缓存,它是位于CPU和内存之间的临时存储器。CPU在读取数据进行计算的时候,首先是从内部的缓存中查找需要的数据,如果有,可以最短时间最快速度交付CPU。但是如果没有找到,CPU就会提出“要求”经过缓存从内存中读取,再原路返回到CPU进行计算。同时,把这个数据所在的数据也调入缓存,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存。

换句话说,CPU中缓存是为了加快CPU读取数据的速度,也是为了给内存一个缓冲期。因为CPU运算速度太快了,光靠内存读写完全跟不上,而CPU缓存的数据交换比内存快多了,大部分时候CPU可以直接从缓存读取数据,找不到的话再从内存读取,这样可以节省CPU读取内存数据时浪费的时间。

二、缓存级别CacheLevel

获取i5处理器的cache信息,如下:

在这里插入图片描述

一般主流CPU有三级缓存L1、L2、L3,并有多个核心。如上图可以看到cache信息:

  • 4个L1 data cache,每个容量32KB
  • 4个L1 instruction cache,每个容量32KB
  • 4个L2 cache,每个容量256KB
  • 1个L3 cache,容量6MB

i5核数刚好也是4核,据此大概也能猜到L1、L2是每个核私有的,而L3是每个核共享的。而实际情况也是如此,核与cache的关系如下所示:

在这里插入图片描述

  • L1容量最小,速度最快,每个核都有L1缓存,L1又专门针对指令和数据分成L1d(数据缓存),L1i(指令缓存)。
  • L2容量比L1大,速度比L1慢,每个核都有L2缓存。
  • L3容量最大,速度最慢,多个核共享一个L3缓存。

CPU获取数据会依次从L1,L2,L3中查找,如果都找不到则会直接向内存查找。

在这里插入图片描述

一般来说,每级缓存的命中率大概都在80%左右,也就是说全部数据量的80%都可以在一级缓存中找到,只剩下20%的总数据量才需要从二级缓存、三级缓存或内存中读取,由此可见一级缓存是整个CPU缓存架构中最为重要的部分。

三、缓存行 CacheLine

计算机将数据从主存读入Cache时,是把要读取数据附近的一部分数据都读取进来
这样一次读取的一组数据就叫做CacheLine,每一级缓存中都能放很多的CacheLine。

在这里插入图片描述

实际上,cache分成了多个组,每个组分成多个CacheLine行,大致如下:

在这里插入图片描述

linesize是cache的基本单位,表示每个cache line的字节数大小。从主存向cache迁移数据都是按照linesize为单位替换的。

比如linesize为32Byte,那么迁移必须一次迁移32Byte到cache。 这个linesize比较容易理解,就像我们从书架往书桌搬书必须以书为单位,肯定不能把书撕了以页为单位。书就是linesize。

当然了现实生活中每本书页数不同,但是同个cache的linesize总是相同的,不仅如此,一般同个CPU中的各级cache,其linesize也是相同的。

使用命令查看linux下cache信息:

getconf -a | grep CACHE

在这里插入图片描述

四、缓存命中与缓存缺失

  • 缓存命中(cache hit)
  • 缓存缺失(cache miss)

当应用程序或软件请求数据时,会首先发生缓存命中。首先,中央处理单元(CPU)在其最近的内存位置(通常是主缓存)中查找数据。如果在缓存中找到请求的数据,则将其视为缓存命中。

CPU要访问的数据在Cache中有缓存,称为“命中” (Hit),反之则称为“缺失” (Miss)。

可以简单理解为:

  • 在各级缓存中找到请求的数据,叫做缓存命中;
  • 请求的数据不在各级缓存中,则叫做缓存缺失。

更加详细的介绍,参考《CACHE的Miss和Hit》一文。

五、Cache line alignment (cache对齐)

数据跨越两个cache line,就意味着两次load或者两次store。如果数据结构是cacheline对齐的, 就有可能减少一次读写。数据结构的首地址cacheline对齐,意味着可能有内存浪费(特别是数组这样连续分配的数据结构),所以需要在空间和时间两方面权衡。

对于普通代码,内存边界对齐也是有好处的,可以降低高速缓存(Cache)和内存交换数据的次数。 主要问题是在于Cache本身是分成很多Cache-Line,每条Cache-Line具有一定的长度,比如一般来说L1 Cache每条CacheLine长度在32个字节或64个字节;而L2的会更大,比如64个字节或128个字节。用户每次访问地址空间中一个变量,如果不在Cache当中,那么就需要从内存中先将数据调入Cache中。

比如现在有个变量 int x;占用4个字节,它的起始地址是0x1234567F;那么它占用的内存范围就在0x1234567F-0x12345682之间。如果现在CacheLine长度为32个字节,那么每次内存同Cache进行数据交换时,都必须取起始地址时32(0x20)倍数的内存位置开始的一段长度为32的内存同Cache Line进行交换。比如0x1234567F落在范围0x12345660-0x1234567F上,但是0x12345680-0x12345682落在范围0x12345680-0x1234569F上,也就是说,为了将4个字节的整数变量0x1234567F-0x12345682装入Cache,我们必须调入两条Cache Line的数据。

但是如果int x的起始地址按4的倍数对齐,比如是 0x1234567C~0x1234567F,那么必然会落在一条Cache Line上,所以每次访问变量x就最多只需要装入一条Cache Line的数据了。比如现在一般的malloc()函数,返回的内存地址会已经是8字节对齐的,这个就是为了能够让大部分程序有更好的性能。

参考链接:

《cpu一级二级三级缓存有什么用?cpu缓存越大越好吗?》

《计算机缓存Cache以及Cache Line详解》

《深入理解Cache》

《Cache Line》

《CPU Cache 机制以及 Cache miss》

《CPU cache 与内存对齐》



若对你有帮助,欢迎点赞、收藏、评论,你的支持就是我的最大动力!!!

同时,阿超为大家准备了丰富的学习资料,欢迎关注公众号“超哥学编程”,即可领取。

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百里杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值