CPU Cache是什么?如何影响其性能?

摘要:Cache Cache 是什么 ? Cache被称为高速缓冲存储器(cache memory),是一种小容量高速的存储器,属于存储子系统的一部分程序常使用的指令和数据。 为什么需要 CPU Cache ? CPU Cache 是为了解决 C
Cache Cache 是什么 ? Cache被称为高速缓冲存储器(cache memory),是一种小容量高速的存储器,属于存储子系统的一部分程序常使用的指令和数据。 为什么需要 CPU Cache ? CPU Cache 是为了解决 CPU 与内存速度差距而设计的高速缓存存储器,通常分为 L1、L2、L3 多级结构,相比主存,Cache的存取速度更快但容量更小,用于存放主存中频繁使用的数据块的副本。 Cache的组成 Cache 是以缓存行(Cache Line) 为基本单元,Cache Line是 CPU 从内存读取数据的最小单位,指的是当CPU试图load一个字节数据的时候,如果cache缺失,那么cache控制器会从主存中一次性的load cache line大小的数据到cache中。为什么load cache line大小的数据到cache中呢?看完局部性原理应该懂了。 局部性原理 局部性原理 是Cache 的理论基础是,包括时间局部性和空间局部性: 时间局部性(temporal locality): 程序中被引入过一次的内存位置很可能在不远的将来再次被多次引用。 空间局部性(spatial locality):在程序中一个内存位置被引用了一次,那么程序很可能在不远的将来引用附近的一个内存位置。 举个例子: int sumvec(int v[N]) { int num = 0; for (int i = 0; i < N; ++i) { sum += v[i]; } return sum; } 对于上面代码段,sum来说,有好的时间局部性。另一方面,因为sum是标量,对于sum来说,没有空间局部性。而向量v是被顺序读取的,一个接一个。因此对于变量v,函数有很好的空间局部性,但是时间局部性很差,因为每个向量元素只被访问一次。 内存地址寻址 我们知道每个字节由八个位组成,"位"是计算机中最基本的存储单元,只能为0或1,规定1B=8bit,大写的“B”就代表是字节。 由于每个位只能是0和1,我们把所有的组合可能都列出来,最后就能发现,1个位能够访问到2个地址,2个位能够访问到4个地址,3个位能够访问到8个地址,也就是2的N次方。 我们假设使用一个64字节大小的内存模型。如果按字节编址全部编址需要6个位。接着就可以引入“字”的概念。“字”的大小是可以变化的,例如令1Word=1Byte,那么这个模型下就有64个字;如果令1Word=2Byte,那么这个模型就有32个字;如果令1Word=4Byte,那么这个模型就有16个字。我们以1Word=4Byte,16个字需要4个位就能全部访问。 为了更好的掩饰,我们更换一下内存模型,此时的每一个“格子”代表了字节,而每一“行”代表了字。 在上面的内存模型中,6位能够访问64个“格”,而4位只能访问16个“行”,缺少的2位就可以被理解为“列”。6位的地址能够直接访问到对应“格”的数据,而先通过4位地址找到对应的“行”,再通过2位地址找到对应的“列”,最后找到的就是6位时访问的“格”。 Cache的读取过程是怎么样的? 现代CPU进行数据读取的时候,无论数据是否已经存储在Cacha中,CPU始终会首先访问Cache。只有当CPU在Cache中找不到数据的时候,才会去访问主存内容,并且将读取到的数据写入Cache中。 问题来了,CPU如何知道要访问的内存数据,存储在Cache的哪个位置呢? CPU实际上是以地址映射的方式来找到主存地址对应的cache地址的 地址映射 主存的数据块大小称为快,cache的数据大小称为行,单个数据称为字。 主存与cache之间是以数据块为单位进行数据交换的,(为什么以整个数据块为数据拷贝呢?答:空间局部性。)主存与cache的数据块大小是相同的。 例如上面是一个64字节大小的内存模型,一个字等于4字节,2个字等于一个块,那么在下图中我们一共有4行cache line,一行cache line就是2个字。所以我们可以利用地址低1bits用来寻址2 字中某一字,我们称这部分bit组合为偏移量(offset)。同理,4行cache line,为了覆盖所有行。我们需要2 bits查找某一行,这部分地址部分称之为索引(index)。我们再看下图中有8个内存块对应4个缓存行,必然会有两个内存块映射同一缓存行,而怎么知道缓存行对应是哪一内存块呢?为了解决这个问题我们使用一位来进行区别,称为标记(tag)。但如果又有新的内存快要映射到这个缓存行呢?单靠一位无法区分三个不同的内存块。为了解决这一问题,我们需要引入不同的映射策略。
阅读全文