如何理解CPU的效率高于内存的效率?本身CPU处理数据,而内存存储数据,如何比较速度?
先来看一张图,这个图可以比较清楚地看到CPU的主要构成及其与主内存的关系。
从上图中可以看出,CPU由多个部分组成,其中包含了算术逻辑单元ALU,控制单元CU,内存管理单元MMU,寄存器register,程序计数器PC,
以及我们今天的主角缓存cache。其中距离ALU最近的存储结构就是寄存器。所以若没有缓存,那么这时候应该比较的就是ALU从寄存器中读取数据的速度与读取主内存的速度。
1.缓存的作用
既然缓存能解决速度不匹配的问题,它是怎么做到的呢?
可以打个比方:外存像出版社,内存像图书馆,而缓存就像手边的书架。我们需要看书时,肯定先看书架上有没有,没有再去图书馆,图书馆也没有才去找出版社。
CPU 也是这样工作的:它先查缓存(L1 → L2 → L3),查到了就称为“命中”,直接处理;如果都查不到,才去内存找。
(有时缓存被视为 CPU 的一部分,这种划分也是合理的。)
如下图所示:
如此,CPU的运行效率就会快很多。因为缓存比内存小。所以很快就可以搜索一遍。而在三级缓存中,L1<L2<L3,所以距离CPU越近的存储结构,
存储空间越小。那为什么设计师会觉得缓存命中率会很高呢?
这是由局部性原理决定的,在计算机学科的概念中,局部性原理分为时间局部性原理和空间局部性原理。
时间局部性:如果一个数据正在被访问,那么在近期它很可能还会被再次访问。 空间局部性:在不久的将来将用到的数据很可能与现在正在使用的数据在空间地址上是临近的。
基于以上的原理,就很容易理解为什么缓存会较高概率会命中了。
2.CPU 的三级缓存结构
缓存存在于内核和主内存中间,总共分为三级(一般情况),
L1 Cache:
在 CPU 核心内部,分为指令缓存和数据缓存,分开存放 CPU 使用的指令和数据; L2 Cache:
在 CPU 核心内部,尺寸比 L1 更大; L3 Cache:
在 CPU 核心外部,所有 CPU 核心共享同一个 L3 缓存。
缓存的存储空间较小,除了高效的要求外,还有个问题,就是制造成本,一般缓存是由SRAM的存储单元构成的,而主内存是由DRAM存储单元构成的。
SRAM的储存单元成本要比RRAM高很多,为了读写高效,SRAM每个存储单元由6个晶体管构成,而DRAM每个存储单元只需要1个晶体管和1个电容器。
3、存储器的金字塔结构
计算机的存储系统通常呈金字塔结构,从上到下包括:
CPU 寄存器:速度最快,容量最小,直接参与运算。
CPU 高速缓存(Cache):位于 CPU 和内存之间,分为 L1、L2、L3 三级,速度快于内存,容量小于内存。
主存(RAM):容量大,速度较慢,用于存储正在运行的程序和数据。
硬盘存储:容量最大,速度最慢,用于长期存储数据。
这种结构旨在在速度、容量和成本之间取得平衡。
4、缓存的工作机制
当 CPU 需要访问数据时,按照以下顺序查找:
L1 Cache:如果命中,直接读取;否则,查找 L2。
L2 Cache:如果命中,将数据加载到 L1,并读取;否则,查找 L3。
L3 Cache:如果命中,将数据加载到 L2 和 L1,并读取;否则,从主存中读取数据,并依次加载到各级缓存。
这种机制确保了数据访问的高效性,减少了对主存的访问次数。
5、缓存一致性与 MESI 协议
在多核处理器中,每个核心有自己的 L1 和 L2 缓存,可能会出现多个缓存中存有相同数据副本的情况。为了保持数据一致性,采用了 MESI 协议,将缓存行的状态分为:
Modified(已修改):缓存中的数据已被修改,主存中为旧数据。
Exclusive(独占):缓存中的数据与主存一致,且只有该缓存拥有此数据。
Shared(共享):多个缓存中有相同的数据副本,数据与主存一致。
Invalid(无效):缓存中的数据无效。
通过 MESI 协议,确保了多核处理器中缓存数据的一致性。
MESI协议的工作原理下篇来讲,先看着图稍微理解一下
6、缓存行与映射方式
缓存以“缓存行”(Cache Line)为单位进行数据存储和管理。常见的缓存映射方式有:
直接映射(Direct Mapping):每个内存块映射到固定的缓存位置,简单但可能导致冲突。
具体方式:
1、将内存块索引对 Cache 块个数取模,得到固定的映射位置。例如 13 号内存块映射的位置就是 13 % 8 = 5,对应 5 号 Cache 块;
2、由于取模后多个内存块会映射到同一个缓存块上,产生块冲突,所以需要在 Cache 块上增加一个 组标记(TAG),标记当前缓存块存储的是哪一个内存块的数据。其实,组标记就是内存块索引的高位,而 Cache 块索引就是内存块索引的低 4 位(8 个字块需要 4 位);
3、由于初始状态 Cache 块中的数据是空的,也是无效的。为了标识 Cache 块中的数据是否已经从内存中读取,需要在 Cache 块上增加一个 有效位(Valid bit) 。如果有效位为 0,则 CPU 可以直接读取 Cache 块上的内容,否则需要先从内存读取内存块填入 Cache 块,再将有效位改为 1。
全相联映射(Fully Associative Mapping):内存块可以映射到任意缓存位置,灵活但查找速度慢。
具体方式:
全相联映射1、当 Cache 块上有空闲位置时,使用空闲位置; 2、当 Cache 被占满时则替换出一个旧的块腾出空闲位置; 3、由于一个 Cache 块会映射所有内存块,因此组标记 TAG 需要扩大到与主内存块索引相同的位数,而且映射的过程需要沿着 Cache 从头到尾匹配 Cache 块的 TAG 标记。 组相联映射(Set Associative Mapping):将缓存分为多个组,内存块映射到某一组内的任意位置,兼顾灵活性和查找速度。
显然,组相联的分组为 1 时就等于全相联映射,而分组等于 Cache 块个数时就等于直接映射。
合理的映射方式可以提高缓存的命中率,提升系统性能。
7、总结
三级缓存不仅仅是三个储物间,更是 CPU 内部一个精密的、高效的数据管理系统。它在处理器与内存之间搭建了高速通道,让 CPU 能够充分发挥运算性能,而不被内存速度所拖累。
如果说 CPU 是大脑,Cache 就是记忆力。记忆力越好,反应越快。