当CPU处理数据时,它会先到Cache中去寻找,如果数据因之前的操作已经读取而被暂存其中,就不需要再从内存中读取数据——由于CPU的运行速度一般比主内存的读取速度快,主存储器周期(访问主存储器所需要的时间)为数个时钟周期。因此若要访问主内存的话,就必须等待数个CPU周期从而造成浪费。
Cache由控制和存储器2部分组成,如上图所示,其中虚线框内为控制部分。Cache的存储器中存放着主存的部分拷贝,其控制部分有3 个功能:
(1) 判断要访问的数据是否在Cache中,若在,为命中;否则,为未命中。
(2) 命中时,进行Cache 的寻址。
(3) 未命中时,按替换原则,确定主存中的信息块要读入到Cache 中的哪个信息块空间。
CPU在缓存中找到有用的数据被称为命中,当缓存中没有CPU所需的数据时(这时称为未命中),CPU才访问内存。从理论上讲,在一颗拥有一级缓存的CPU中,读取一级缓存的命中率为80%。也就是说CPU一级缓存中找到的有用数据占数据总量的80%,剩下的20%从二级缓存中读取。由于不能准确预测将要执行的数据并将其预读到缓存中,读取二级缓存的命中率也在80%左右(从二级缓存读到有用的数据占总数据的16%)。那么还有的数据就不得不从内存调用,但这已经是一个相当小的比例了。较高端的CPU中,还会带有三级缓存,它是为读取二级缓存后未命中的数据设计的—种缓存,在拥有三级缓存的CPU中,只有约5%的数据需要从内存中调用,这进一步提高了CPU的效率。
拥有144MB缓存的八路IBM POWER5处理器
但这个比例也不是绝对的,因为随着软件的发展,需要越来越多的缓存来预存将要运算的数据,如果缓存的容量不随着软件的发展而增大,就会出现不够用的情况。
另外在处理器缓存的发展中,Intel和AMD的处理器一级缓存在逻辑结构设计上在Core之前并不一样。AMD对一级缓存的定位是“实数据读写缓存”,基于该架构的一级数据缓存主要用于存储CPU最先读取的数据;而更多的读取数据则分别存储在二/三级缓存和系统内存当中。即二级/三级缓存中的一部分数据都要在一定的规则下搬到一级缓存中。二级缓存的容量自然对AMD CPU的整体性能影响小些。相对的,AMD则总是试图把一级缓存做的更大些。
Intel在对Core之前一级缓存的理解是“数据代码指令追踪缓存”,即是说一级缓存中存储的其实只是二级缓存中数据的地址,而不是这些数据的复制。由于一级数据缓存不再存储实际数据,因此“数据代码指令追踪缓存”设计能够极大地降CPU对一级数据缓存容量的要求,降低处理器的生产难度。但这种设计的弊端在于数据读取效率较“实数据读写缓存设计”低,而且对二级缓存容量的依赖性非常大。
事实上CPU性能对二级缓存容量的“敏感”与否还受到诸如内存控制器,流水线长度、频率、总线架构和指令集等等多方面的影响。在多核CPU中还关乎各个物理内核之间的数据交换问题。从Core开始,Intel开始采用“实数据读写缓存”,而目前最新的Nehalm架构则像AMD一样,把内存控制器集成在CPU内部,并更新了总线。这一方面说明了AMD在CPU架构设计上的强项,另一方面在Intel采用AMD的这种占优势的存储架构之后,AMD的优势将被进一步削弱。
这里还涉及到一个问题:CPU提供给Cache的地址是主存的地址,要访问Cache,就必须将这个地址变换成Cache 的地址,这种地址变换为地址映射,Cache的地址映射有直接映射、全相联映射和组相联映射三种,目前的主流CPU都是采用组相联。