电子百科
CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多。缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,因为CPU运算速度要比内存读写速度快很多,这样会使CPU花费很长时间等待数据到来或把数据写入内存。在缓存中的数据是内存中的一小部分,但这一小部分是短时间内CPU即将访问的,当CPU调用大量数据时,就可避开内存直接从缓存中调用,从而加快读取速度。由此可见,在CPU中加入缓存是一种高效的解决方案,这样整个内存储器(缓存+内存)就变成了既有缓存的高速度,又有内存的大容量的存储系统了。缓存对CPU的性能影响很大,主要是因为CPU的数据交换顺序和CPU与缓存间的带宽引起的。
在现代CPU设计中,设计师们要解决的最主要问题,就是找到一个在CPU和内存之间平衡的均点。Cache作为CPU---内存的中转站,在其中发挥了巨大的作用。CPU在请求数据或指令时,除了常规的在内存中进行查找外,还会在Cache中进行查找。一旦命中,就可以直接从Cache中读取,节约大量时间。正因为如此,CPU缓存在现代CPU中显得越来越重要。
众所周知,CPU缓存属于SRAM(Satic Random Access Memory),它利用晶体管的逻辑开关状态来存取数据。也正因为如此,SRAM内部的电路构造比起常见的DRAM(Dynamic Random Memory)要复杂得多,导致了成本的巨增。这也是SRAM不能普及的一个重要原因。
CPU缓存在计算机存储系统中没有编配固定的地址,这样程序员在写程序时就不用考虑指令是运行在内存中还是Cache中,Cache对于计算机上层来说是完全透明的。
CPU在读取数据时,会首先向内存和Cache都发送一个查找指令。如果所需要的数据在Cache中(命中),则直接从Cache读取数据,以节约时间和资源。CPU对Cache的搜索叫做Tag search,即通过Cache中的CAM(Content Addressed Memory)对希望得到的Tag数据进行搜索。CAM是一种存储芯片,延迟很低,常用于网络设备中用作路由选择。
CPU进行Tag search的过程是这样的:在Cache中数据或指令是以行为单位存储的,一行又包含了很多字。如现在主流的设计是一行包含64Byte。每一行拥有一个Tag。因此,假设CPU需要一个标为Tag 1的行中的数据,它会通过CAM对Cache中的行进行查找,一旦找到相同Tag的行,就对其中的数据进行读取。
在现代计算机中,虽然Cache的容量一直在增涨,但现在桌面处理器中Cache最大的也不过4MB,设计师们是如何保证在这小小的Cache中保存的数据或指令就一定是CPU需要的呢?这就要利用到CPU运行时的两个基本局限性:时间局限性和空间局限性。
所谓时间局限性,是指CPU在某一时刻使用到的数据或指令,在下一时刻也会被重复利用。比如3D游戏中,同一场景会在不同时间被渲染多次,如果在第一次渲染中Cache存储了相关指令、数据,那么在下一次需要重复渲染时,就能够直接从Cache中读取相关内容。
而空间局限性,指的是CPU在读取某一地址的数据时,也有可能会用到该地址附近的数据。也就是说,CPU需要的数据在很多时候是连续的。例如在听歌或看电影时,数据流总是连续的(正常播放状态下)。这样的应用对于CPU来说是很有利的,数据预读取单元也能够发挥最大作用。
CPU缓存正是利用了上述两个局限性,得已实现并工作。设计师们能够充分利用这两个局限,在容量较小的Cache中存入CPU在将来某时刻需要的内容。需要指出的是,很多程序在执行指令或数据时,所呈现出来的局限性是不同的。有可能执行指令的时候呈现出时间局限性,而数据呈现出空间局限性,因此设计师们把L1 Cache分成了Instruction Cache(指令缓存)和Data Cache(数据缓存)。
前面已经说过,Cache的数据存储是以行(Line)为单位的,每一行又包含64Byte。行是存储在“框架”(Block frame)这种数据容器中的,而框架则直接与内存相对应。很明显,Cache中可能包含数个框架。那么这些Cache框架是怎么与内存相对应相联系的呢?有三种办法。
第一种方法叫完全相联法。即内存中的数据可以存储在任何Cache框架中,同一数据也可以存储在不同的框架中。这样数据的存储相当灵活,CPU在查找时也很方便:只需在框架中对比找出需要的Tag行,即实现命中,显着的提升了命中率。然而这样做的缺陷也很明显:对于容量较大的Cache来说,CPU需要在成百的框架中查找需要的Tag行,延迟大大增加。因此这种设计方式只适用于容量较小的Cache。
由于完全相联法的这种局限性,设计师们很快提出了另一种旨在降低延迟的组织方式:直接映象法。和完全相联不同,在直接映象中内存会将数据存入的Cache框架地址“记住”,以后再次存储时就只能使用该框架。这样做的好处是使CPU只需要进行一次Tag search,在以后的读取操作中就可以直接找到所需Tag行所在的框架,从而达到降低延迟的目的。
而至于内存会将数据存入Cache的哪个框架中,这有个算法——块地址与整个框架数的同余。我们举个简单的例子来看,有个1K的缓存,块大小为64字节,则总共有16个缓存块,也就是有16个框架,那在内存中首地址为12480的内存块应该保存在缓存的哪个框架中呢?12480/64=195,195mod16=3,则它应该放入第4个框架中。这样一来,内存中的数据能很快的读取到缓存中的某个块中,CPU也能很快的在这个块中找到所要的数据,这样就省下了对比各个框架的时间,自然延迟就小了,但是,如果第4个框架中装入了内存块195的数据,而其它同余依然是3的35,51,67等这些块就不能装入了,这样,当CPU需要35,51,67这些块的时候,就会发生冲突(collision),导致出现Cache miss的情况,大大的降低了命中率。
按照数据读取顺序和与CPU结合的紧密程度,CPU缓存可以分为一级缓存,二级缓存,部分高端CPU还具有三级缓存,每一级缓存中所储存的全部数据都是下一级缓存的一部分,这三种缓存的技术难度和制造成本是相对递减的,所以其容量也是相对递增的。当CPU要读取一个数据时,首先从一级缓存中查找,如果没有找到再从二级缓存中查找,如果还是没有就从三级缓存或内存中查找。一般来说,每级缓存的命中率大概都在80[%]左右,也就是说全部数据量的80[%]都可以在一级缓存中找到,只剩下20[%]的总数据量才需要从二级缓存、三级缓存或内存中读取,由此可见一级缓存是整个CPU缓存架构中最为重要的部分。
1)一级缓存
一级缓存(Level 1 Cache)简称L1 Cache,位于CPU内核的旁边,是与CPU结合最为紧密的CPU缓存,也是历史上最早出现的CPU缓存。由于一级缓存的技术难度和制造成本最高,提高容量所带来的技术难度增加和成本增加非常大,所带来的性能提升却不明显,性价比很低,而且现有的一级缓存的命中率已经很高,所以一级缓存是所有缓存中容量最小的,比二级缓存要小得多。
2)二级缓存
二级缓存是CPU的第二层高速缓存,分内部和外部两种芯片。内部的芯片二级缓存运行速度与主频相同,而外部的二级缓存则只有主频的一半。L2高速缓存容量也会影响CPU的性能,原则是越大越好,现在家庭用CPU容量最大的是4MB,而服务器和工作站上用CPU的L2高速缓存更高达2MB—4MB,有的高达8MB或者19MB。
3)三级缓存
三级缓存分为两种,早期的是外置,现在的都是内置的。而它的实际作用即是,L3缓存的应用可以进一步降低内存延迟,同时提升大数据量计算时处理器的性能。降低内存延迟和提升大数据量计算能力对游戏都很有帮助。而在服务器领域增加L3缓存在性能方面仍然有显着的提升。比方具有较大L3缓存的配置利用物理内存会更有效,故它比较慢的磁盘I/O子系统可以处理更多的数据请求。具有较大L3缓存的处理器提供更有效的文件系统缓存行为及较短消息和处理器队列长度。
一级缓存和二级缓存用于存储数据的缓存部分通常被称为RAM,掉电以后其中的信息就会消失。
RAM又分两种,其中一种是静态RAM(SRAM);另外一种是动态RAM(DRAM)。前者的存储速度要比后者快得多,我们现在使用的内存一般都是动态RAM。CPU的L1级缓存通常都是静态RAM,速度非常的快,但是静态RAM集成度低(存储相同的数据,静态RAM的体积是动态RAM的6倍),而且价格也相对较为昂贵(同容量的静态RAM是动态RAM的四倍)。扩大静态RAM作为缓存是一个不太合算的做法,但是为了提高系统的性能和速度又必须要扩大缓存,这就有了一个折中的方法:在不扩大原来的静态RAM缓存容量的情况下,仅仅增加一些高速动态RAM做为L2级缓存。高速动态RAM速度要比常规动态RAM快,但比原来的静态RAM缓存慢,而且成本也较为适中。一级缓存和二级缓存中的内容都是内存中访问频率高的数据的复制品(映射),它们的存在都是为了减少高速CPU对慢速内存的访问。
二级缓存是CPU性能表现的关键之一,在CPU核心不变化的情况下,增加二级缓存容量能使性能大幅度提高。而同一核心的CPU高低端之分往往也是在二级缓存上存在差异,由此可见二级缓存对CPU的重要性。CPU在缓存中找到有用的数据被称为命中,当缓存中没有CPU所需的数据时(这时称为未命中),CPU才访问内存。
从理论上讲,在一颗拥有二级缓存的CPU中,读取一级缓存的命中率为80[%]。也就是说CPU一级缓存中找到的有用数据占数据总量的80[%],剩下的20[%]从二级缓存中读取。由于不能准确预测将要执行的数据,读取二级缓存的命中率也在80[%]左右(从二级缓存读到有用的数据占总数据的16[%])。那么还有的数据就不得不从内存调用,但这已经是一个相当小的比例了。
三级缓存是为读取二级缓存后未命中的数据设计的—种缓存,在拥有三级缓存的CPU中,只有约5[%]的数据需要从内存中调用,这进一步提高了CPU的效率。