嵌入式C语言自我修养:从芯片、编译器到操作系统
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.4 CPU性能提升:Cache机制

随着半导体工艺和芯片设计技术的发展,CPU的工作频率也越来越高,和CPU进行频繁数据交换的内存的运行速度却没有相应提升,于是两者之间就产生了带宽问题,进而影响计算机系统的整体性能。CPU执行一条指令需要零点几纳秒,而RAM则需要30纳秒左右,读写一次RAM的时间,CPU都可以执行几百条指令了。为了不给CPU拖后腿,解决内存带宽瓶颈的方法一般有两个:一是大幅提升内存RAM的工作频率,目前最新的DDR4内存条的工作频率可以飙到2GHz,但是和高端的CPU相比,还是存在一定差距的,这就需要第二种方法来弥补差距:使用Cache缓存机制。有速度瓶颈的地方就有缓存,这种思想在计算机中随处可见。

2.4.1 Cache的工作原理

Cache在物理实现上其实就是静态随机访问存储器(Static Random Access Memory,SRAM),Cache的运行速度介于CPU和内存DRAM之间,是在CPU和内存之间插入的一组高速缓冲存储器,用来解决两者速度不匹配带来的瓶颈问题。Cache的工作原理很简单,就是利用空间局部性和时间局部性原理,通过自有的存储空间,缓存一部分内存中的指令和数据,减少CPU访问内存的次数,从而提高系统的整体性能。

Cache的工作流程以图2-28为例:当CPU读取内存中地址为8的数据时,CPU会将内存中地址为8的一片数据缓存到Cache中。等下一次CPU读取内存地址为12的数据时,会首先到Cache中检查该地址是否在Cache中。如果在,就称为缓存命中(Cache Hit),CPU就直接从Cache中取数据;如果该地址不在Cache中,就称为缓存未命中(Cache Miss),CPU就重新转向内存读取数据,并重新缓存从该地址开始的一片数据到Cache中。

图2-28 通过Cache缓存RAM中的数据

CPU写内存的工作流程和读类似:以图2-29为例,当CPU往地址为16的内存写入数据0时,并没有真正地写入RAM,而是暂时写到了Cache里。此时Cache和内存RAM的数据就不一致了,缓存的每块空间里一般会有一个特殊的标记位,叫“Dirty Bit”,用来记录这种变化。当Cache需要刷新时,如Cache空间已满而CPU又需要缓存新的数据时,在清理缓存之前,会检查这些“Dirty Bit”标记的变化,并把这些变化的数据回写到RAM中,然后才腾出空间去缓存新的内存数据。

图2-29 Cache的回写过程

以上只是对Cache的工作原理做了简化分析,实际的Cache远比这复杂,如Cache里存储的内存地址,一般要经过地址映射,转换为更易存储和检索的形式。除此之外,现代的CPU为了进一步提高性能,大多采用多级Cache:一级Cache、二级Cache,甚至还有三级Cache。

2.4.2 一级Cache和二级Cache

CPU从Cache里读取数据,如果缓存命中,就不用再访问内存,效率大大提升;如果缓存未命中,情况就不太乐观了:CPU不仅要重新到内存中取数据,还要缓存一片新的数据到Cache中,如果Cache已经满了,还要清理Cache,如果Cache中的数据有“Dirty Bit”,还要回写到内存中。这一波操作可能需要几十甚至上百个指令,消耗上百个时钟周期的时间,严重影响了CPU的读写效率。为了减少这种情况发生,我们可以通过增大Cache的容量来提高缓存命中的概率,但随之带来的就是成本的上升。在CPU内部,Cache和寄存器的电路比内存DRAM复杂了很多,会占用很大的芯片面积,如果大量使用,芯片发热量会急剧上升,所以在CPU内部寄存器一般也就几十个,靠近CPU的一级Cache也就几十千字节。既然无法继续增加一级Cache的容量,一个折中的办法就是在一级Cache和内存之间添加二级Cache,如图2-30所示。二级Cache的工作频率比一级Cache低,但是电路成本会降低,元器件的运行速度总是和电路成本成正比。

图2-30 CPU处理器中的多级Cache

现在的CPU一般都是多核结构,一个CPU芯片内部会集成多个Core,每个Core都会有自己独立的L1 Cache,包括D-Cache和I-Cache。在X86架构的CPU中,一般每个Core也会有自己独立的L2 Cache,L3 Cache被所有的Core共享。而在ARM架构的CPU中,L2 Cache则被每簇(Cluster)的Core共享。ARM架构SoC芯片的存储结构如图2-31所示。

图2-31 ARM架构多核CPU的存储结构

2.4.3 为什么有些处理器没有Cache

通过前两节的学习,我们已经知道Cache的作用主要是缓解CPU和内存之间的带宽瓶颈。Cache一般用在高性能处理器中,并不是所有的处理器都有Cache,如C51系列单片机、cortex-M0、cortex-M1、cortex-M2、cortex-M3、cortex-M4系列的ARM处理器都没有Cache。为什么这些处理器不使用Cache呢?主要原因有三个:一是这些处理器都是低功耗、低成本处理器,在CPU内集成Cache会增加芯片的面积和发热量,不仅功耗增加,芯片的成本也会增加不少。以Intel酷睿i7-3960X处理器为例,如图2-32所示,L3 Cache大约占了芯片面积的1/4,再加上每个Core内部集成的独立L1 Cache和L2 Cache,整个Cache面积差不多就占了芯片总面积的1/3。

图2-32 i7-3960x处理器的设计版图

二是这些处理器本来工作频率就不高(从几十兆赫到几百兆赫不等),和RAM之间不存在带宽问题,有些处理器甚至不需要外接RAM,直接使用片内SRAM就可满足面向控制领域的软件开发需求。

三是使用Cache无法保证实时性。当缓存未命中时,CPU从RAM中读取数据的时间是不确定的,这是嵌入式实时控制场景无法接受的。因此,在一些面向嵌入式工业控制、实时领域、超低功耗的处理器中,大家可以看到很多没有集成Cache的处理器。不要觉得奇怪:适合自己的,才是最好的,不是所有的牛奶都叫特仑苏,不是所有的处理器都需要Cache。