4路组相连cache设计_cache基本原理

v2-d8a70c92f3fbc27028b2f535aaf3a718_1440w.jpg?source=172ae18b

为什么要了解cache:

在学习linux kernel的过程,经常会cache的概念,从软件层面的page/buffer cache;再到硬件层面中CPU的L1 L2 L3 cache 、TLB,磁盘内部的硬件cache;以及编程时的cacheline对齐,slab着色等等。cache是我们始终绕不开的一个主题,本文主要介绍处理器内部的硬件高速缓存。

为什么要使用cache:

原因很简单,提速。CPU处理指令的速度远远快于访问主存的速度,若频繁的访问主存,会大幅拉低整个系统执行程序的效率,而CPU访问cache的速度则很快,快到和系统访问CPU内部寄存器的速度接近,所以使用cache能减少CPU访问主存的次数,从而达到系统提速的目的。

cache预备知识:

  • cache line是什么:

每个内存地址代表的存储单元是1 byte,cache和内存之间传输却不是以单个byte进行的,而是以cache line为单元。常见的cache line大小有32、64、128 bytes。使用cache line很明显的一个原因是利用了程序访问的空间局部性,短时间内程序访问内存空间中的数据或是指令大概率会在一段连续的地址范围内,所以一次性从主存中取一段cache line大小的连续内存,可以减少访问内存的次数。

  • cache的关联方式:

cache通过关联方式被分为直接映射cache、多路组相连cache以及全相连cache。如果一块内存数据(大小为一个cache line ),只有一个cache line与之对应,我们称之为直接映射(Direct mapped);如果该块内存数据可以和cache中的任意一个cache line对应,则称之为全相联(Full-Associative)。而目前更多的实现方式是采用多路组相连(N-Way Set-Associative),即一块内存数据可以对应到N个cache line上。

多路组相连(N-way Set Associative):

ARMv8架构的cortex-a57的L1 D-cache采用了2路组相连缓存(2-ways set associative), I-cache采用了3路组相连缓存;L2的I-cache和D-cache都使用了16路组相连缓存。

我们知道当CPU去读取某地址的内存前,会先去访问cache,如果cache命中就直接从cache里获取数据。那检查命中是怎么个流程呢?

假设我们有一个32KB的cache是4路组相连,且cache line大小为32 bytes。那么组的大小是32KB/4=8KB,每组的cache line数量是8KB/32B=256个。再限定CPU地址位宽是48bit,那判断cache是否命中的信息就全在这48个bit中了。

bit0--bit4(2^5=32)用来确定cache line中的32个byte具体哪个byte;bit5--bit12(2^8=256)用来确定256个cacheline中具体哪路cacheline(由于我们有4路,所以会找到4个cacheline),如何确定是4路中的哪一路呢?而且如果只依据bit5--bit12去定位cacheline,那将会有2^35个可能对应到这4路cache line。所以每个cache line还会配一个tag用来解决上面的两个问题,tag存储了cache line对应内存地址的bit47--bit13,这样所有的地址都用上了,从而能对应到唯一的一条cache line(对应不到?那就是cache miss咯)。

v2-535517087fddfc76283128c1ed3c9e96_b.jpg

如上图。关于cache line中的flags,每个cache line还会包含V(valid)和D(dirty)的两个flags用于表示当前cache line是否valid,以及cache line中的数据是否dirty,有点类似于多级页表中PTE上的present和dirty位。

直接映射缓存(Direct-mapped cache):

直接映射的方式可大致等同与多路组相连中1路组相连的情况。但从缓存效果上看,直接映射的缺点(还用上面的32KB cache举例)在于:每个bit5--bit12的地址一样的内存块有2^35个,而这2^35个内存块只能对应一个index固定的cache line,若该cache line缓存了一块内存数据,那下次再有数据落在这2^35个可能中的任意一内存块中,前一个cache line中的数据就会被冲掉,还要重新访问内存填充cache line,这种情况被成为cache颠簸(cache thrashing)。于是出现了多路组相连缓存,更多的组可以减少cache thrashing发生的概率。

全相连缓存(Full associative cache):

全相连缓存可以理解为直接映射缓存中去掉index段,bit5--bit47全部存放在tag中,没有了index的限制,意味着每条cache line可以对应任意一个内存块。你可能会觉得这样不是最好的吗?倘若cache较大时,cache line就会变得很多很多,当判断是否cache hit时,需要遍历大量的tag,不够高效,且增加了硬件设计的复杂性。所以全相连只适用于cache容量较小的情况。

参考文献: https:// en.wikipedia.org/wiki/C PU_cache
Documentation - Arm Developer

原创文章,转载和引用请注明出处。

作者:Yann Xu

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值