《深入浅出DPDK》—第2章2.2节Cache系统简介
本节书摘来自华章出版社《深入浅出DPDK》一书中的第2章,第2.2节Cache系统简介,作者朱河清,梁存铭,胡雪焜,曹水 等,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
2.2 Cache系统简介
随着计算机行业的飞速发展,CPU的速度和内存的大小都发生了翻天覆地的变化。英特尔公司在1982年推出80286芯片的时候,处理器内部含有13.4万个晶体管,时钟频率只有6MHz,内部和外部数据总线只有16位,地址总线24位,可寻址内存大小16MB。
而英特尔公司在2014年推出的Haswell处理器的时候,处理器内部仅处理器本身就包含了17亿个晶体管,还不包括Cache和GPU这种复杂部件。时钟频率达到3.8GHz,数据总线和地址总线也都扩展到了64位,可以寻址的内存大小也已经开始以TB(1T=1024GB)计算。
在处理器速度不断增加的形势下,处理器处理数据的能力也得到大大提升。但是,数据是存储在内存中的,虽然随着DDR2、DDR3、DDR4的新技术不断推出,内存的吞吐率得到了大大提升,但是相对于处理器来讲,仍然非常慢。一般来讲,处理器要从内存中直接读取数据都要花大概几百个时钟周期,在这几百个时钟周期内,处理器除了等待什么也不能做。在这种环境下,才提出了Cache的概念,其目的就是为了匹配处理器和内存之间存在的巨大的速度鸿沟。
2.2.1 Cache的种类
一般来讲,Cache由三级组成,之所以对Cache进行分级,也是从成本和生产工艺的角度考虑的。一级(L1)最快,但是容量最小;三级(LLC,Last Level Cache)最慢,但是容量最大,在早期计算机系统中,这一级Cache也可以省略。不过在当今时代,大多数处理器都会包含这一级Cache。
Cache是一种SRAM,在早期计算机系统中,一般一级和二级Cache集成在处理器内部,三级Cache集成在主板上,这样做的主要原因是生产工艺的问题,处理器内部能够集成的晶体管数目有限,而三级Cache又比较大,从而占用的晶体管数量较多。以英特尔最新的Haswell i7-5960X为例,一级Cache有32K,二级有512K,但是三级却有20M,在早期计算机系统中集成如此大的SRAM实在是很难做到。不过随着90nm、45nm、32nm以及22nm工艺的推出,处理器内部能够容纳更多的晶体管,所以三级Cache也慢慢集成到处理器内部了。
图2-4是一个简单的Cache系统逻辑示意图。
一级Cache,一般分为数据Cache和指令Cache,数据Cache用来存储数据,而指令Cache用于存放指令。这种Cache速度最快,一般处理器只需要3~5个指令周期就能访问到数据,因此成本高,容量小,一般都只有几十KB。在多核处理器内部,每个处理器核心都拥有仅属于自己的一级Cache。
二级Cache,和一级Cache分为数据Cache和指令Cache不同,数据和指令都无差别地存放在一起。速度相比一级Cache慢一些,处理器大约需要十几个处理器周期才能访问到数据,容量也相对来说大一些,一般有几百KB到几MB不等。在多核处理器内部,每个处理器核心都拥有仅属于自己的二级Cache。
三级Cache,速度更慢,处理器需要几十个处理器周期才能访问到数据,容量更大,一般都有几MB到几十个MB。在多核处理器内部,三级Cache由所有的核心所共有。这样的共享方式,其实也带来一个问题,有的处理器可能会极大地占用三级Cache,导致其他处理器只能占用极小的容量,从而导致Cache不命中,性能下降。因此,英特尔公司推出了Intel? CAT技术,确保有一个公平,或者说软件可配置的算法来控制每个核心可以用到的Cache大小。在此,本书就不再赘述。
对于各级Cache的访问时间,在英特尔的处理器上一直都保持着非常稳定,一级Cache访问是4个指令周期,二级Cache是12个指令周期,三级Cache则是26~31个指令周期。这里所谓的稳定,是指在不同频率、不同型号的英特尔处理器上,处理器访问这三级Cache所花费的指令周期数是相同的。请参照[Ref2-2]。
除了上述的Cache种类之外,还包含一些其他类型,接下来的章节会接着介绍。
2.2.2 TLB Cache
在早期计算机系统中,程序员都是直接访问物理地址进行编程,当程序出现错误时,整个系统都瘫痪掉;或者在多进程系统中,当一个进程出现问题,对属于另外一个进程的数据或者指令区域进行写操作,会导致另外一个进程崩溃。因此,随着计算机技术的进步,虚拟地址和分段分页技术被提出来用来保护脆弱的软件系统。软件使用虚拟地址访问内存,而处理器负责虚拟地址到物理地址的映射工作。为了完成映射工作,处理器采用多级页表来进行多次查找最终找到真正的物理地址。当处理器发现页表中找不到真正对应的物理地址时,就会发出一个异常,挂起寻址错误的进程,但是其他进程仍然可以正常工作。
页表也存储在内存中,处理器虽然可以利用三级Cache系统来缓存页表内容,但是基于两点原因不能这样做。一种原因下面的段落会讲到,我们先讲另外一个原因。处理器每当进行寻址操作都要进行一次映射工作,这使得处理器访问页表的频率非常得高,有可能一秒钟需要访问几万次。因此,即使Cache的命中率能够达到99%以上,也就是说不命中率有1%,那么不命中的概率每秒也有几百次,这会导致处理器在单位时间内访问内存(因为Cache没有命中,只能访问内存)的次数增多,降低了系统的性能。
因此,TLB(Translation Look-aside Buffer)Cache应运而生,专门用于缓存内存中的页表项。TLB一般都采用相连存储器或者按内容访问存储器(CAM,Content Addressable Memory)。相连存储器使用虚拟地址进行搜索,直接返回对应的物理地址,相对于内存中的多级页表需要多次访问才能得到最终的物理地址,TLB查找无疑大大减少了处理器的开销,这也是上文提到的第二个原因。如果需要的地址在TLB Cache中,相连存储器迅速返回结果,然后处理器用该物理地址访问内存,这样的查找操作也称为TLB命中;如果需要的地址不在TLB Cache中,也就是不命中,处理器就需要到内存中访问多级页表,才能最终得到物理地址。