所谓的高速缓存(CPU Cache),就是我们常说的一级,二级,三级缓存。也是嵌入在CPU芯片中的芯片组。访问速度逐级减小而容量增加增大。
在我们日常使用的Inter服务器或者PC里面,CPU Cache一般都是64个字节。当我们在计算机上运行程序时,会将运行程序所需要的数据从内存加载到CPU Cache中,而加载的方式,就是以每次64字节这样一小块一小块加载到CPU Cache中的,这也是我们常常听说的缓存块!
![eb556533685c48f7216a1640724b9c19.png](https://i-blog.csdnimg.cn/blog_migrate/33ae0a74d5552da0b35fffee1bd438c4.jpeg)
在CPU读取数据的时候,会先去访问Cache,只有当Cache中没有数据时,CPU才会去访问内存。并将读取到的数据写入到Cache中(局部性原理,每一层Cache中都缓存最近使用的数据)。由于Cache的访问速度比内存快很多,所以CPU就不必花太多的时间在数据读取上,这个过程就好像我们在Web开发中的加一个缓存层。
运行程序经过编译汇编之后会分配对应的内存地址,并没有对应的高速缓存地址,CPU可以直接根据这个内存地址去读取所需要的数据,如果是在Cache中,那CPU是如何知道对应内存地址的数据,是在Cache中哪个位置呢?
直接映射 Cache(Direct Mapped Cache)
CPU读取数据是按内存块来读取,CPU读取内存的地址,如何通过这个内存地址定位到Cache中的块地址呢?计算机的设计大佬们通过mod运算来做直接映射关系:任何一个内存块的地址都始终映射到一个固定的Cache Line的块上。什么意思呢:
![e4404a2a62d2f3034dd9f37ac5883a7e.png](https://i-blog.csdnimg.cn/blog_migrate/1fc6f62e13dd9683a8182b38b189cf21.jpeg)
假如内存被划分为32个内存块,Cache被划分为8个 Cache Line,想要访问第29号内存块,就用第N个 Cache mod 8(总Cache Lin量),于是发现29号内存块的数据在 Cacle Line 5上面。一般来说,内存和 Cache 会被划分为2^N 块,这样做的好处是,假设 Cache 被划分为块为 2^3 内存被划分为32块为 2^5,那么第 N 个内存 块 的 二 进制数的低3位就是对应的Cache Line 的位置。这就是二进制的妙处!!
![23cbd027f95c500b28e5c40b273d2d45.png](https://i-blog.csdnimg.cn/blog_migrate/d660e9b4ad26415ea5af8b4b874c7a67.png)
目前为止,程序所需要的数据可以通过内存块的地址定位到高速缓存地址(如果数据存在高速缓存中的话,就算不存在也会找一遍~),那么又有问题了:CPU怎么知道这个块上的数据就是我需要的数据呢,就像hash函数一样,32个内存地址块mod到8个高速缓存块,肯定会有落在同一个Cache Line中的地址。这个时候大佬们又添加了一个组标记的东东,就像上面的图里面的,第三位101表示Cache Line中的位置,高两位表示是哪个内存块上的数据!
但是仅仅有组标记还是不够的,我们只是确定了内存被映射到的 Cache 的块中,这个块中还存储着很多来自这个内存中的很多数据。那么怎么确定想要读取的具体数据呢?所以缓存块中还需要记录更多的信息一个是偏移量(offset),就是数据在块中的相对位置。
还有一个就是有效位(valid bit)。有效位就是来标记对应的缓存块中的数据是否是有效的,确保不是机器刚刚启动时候的空数据。如果有效位是 0,无论其中的组标记和 Cache Line 里的数据内容是什么,CPU 都不会管这些数据,而要直接访问内存,重新加载数据。
所以最后抽象出来高速缓存和内存地址的对应关系就如图:
![88db5dd011b12bc4ca891208fd5f6092.png](https://i-blog.csdnimg.cn/blog_migrate/884be64d3305659a91a6363b4b39271b.jpeg)
所以 Cache 中通过索引(偏移量)+有效位+组标记+数据的组合,可以让CPU准确的直接从 Cache 中加载内存地址对应的 Cache 中的数据。而CPU从 Cache 中读取数据需要经过以下步骤:
1.通过内存地址的低位确定对应 Cache 中的位置。
2.判断有效位,数据有效就进行下面操作,无效则从内存中读取。
3.对比内存地址的高位和Cache中的组标记,判断是否就是要访问的内存数据,如果是就从 Cache 块中读取数据。
4.通过偏移位读取具体的数据。