story · 2022年06月10日

cache学习系列2:cathe的缺点,直接映射cache及组相联cache

cache有哪些缺点

很多时候大家谈论cache都只会谈及各种好处,比如加快程序执行的速度,减少主存的访问。

但是,cache还引入了没有cache的系统不存在的一些问题。

其中一个缺点就是,程序的执行时间变得不确定

因为cache很小并且只保存主存的一个子集,cache会在程序执行时迅速填满。当cache被填满时,必须删除(evict)现有指令或数据以为新的指令或者数据腾出空间。

因此,在任何给定时间,程序或者程序员都无法确定是否能够在cache中找到特定的指令或数据

  • 实时系统

这意味着不同cache状态下特定程序的执行时间可能会有很大差异。所以,在实时系统(强调确定性)中,cache行为的不确定性是一个很大的问题。

  • 外设空间

有时,程序员希望能够立马从外设寄存器中读取最新数据,例如timer,这个时候外设寄存器的值就不应该填充到cache中。

  • cache写回策略

有时,我们希望确认处理器内核写入的数据已经到达内存,而不是仅停留在cache中。

  • cache一致性

有时,cache和主存的内容可能不一样,这是因为处理器更新了cache的内容,这些内容还没有写回(write-back)。或者多个内核共享内存,其中一个内核修改了主存,而另一个内核的cache中还包含旧的无效数据。

上述这几个示例问题都是由于cache的引入导致的。总之,世界变得复杂了。

直接映射cache

有多种实现cache的组织方式,其中最简单的是直接映射cache

在直接映射cache中,主存中的每个位置都只能映射到某个特定的cache位置。由于主存比cache大很多倍,所以许多主存地址会映射到cache上的同一个位置。下图显示了包含4个caceline,每个cacheline包含4个字的cache。

d1ce785206c5bf64a0675b47484423aa.png

offset-index-tag

cache将使用访问地址比特[3:2]作为offset来选择cacheline中的一个字。地址比特[5:4]作为index选择4个cacheline中一个。地址的其余比特 [31:6]作为tag存储在cache中。

f6cb25fa90fb41d24a3289ddcfc9a4cb.png

hit

为了在cache中查找特定地址,硬件根据地址中的index读取cache中相应的tag。如果tag和地址中cache tag域段相同,并且该cache有效状态位表示该cacheline包含有效数据,则为命中(hit)。然后,使用地址的offset从cacheline中提取相应的字。

miss

如果该cache line有效状态位表示该cacheline没有包含有效数据或者tag比对不通过,则没有命中(miss),然后需要将主存中的数据填到cache中,地址相应域段填入cache tag中,最后还要置起有效状态位。

cache颠簸

在直接映射中,所有具有相同比特 [5:4] index的主存地址将映射到cache中的同一个cacheline。在任何给定时间,这些地址数据只有一个可以在cache中。这意味着很容易发生颠簸(thrashing的问题。考虑下面这个循环代码,重复访问地址 0x00、0x40 和 0x80 :

cd9d365f4a9734ab1b8ede42eb672393.png

在此代码示例中,如果 result、data1 和 data2 分别是指向 0x00、0x40 和 0x80 的指针,则此循环将导致对cache line index 0位置的颠簸。

  • 第一次读取地址 0x40 时,它不会在cache中,因此会发生linefill ,将 0x40 到 0x4F 的数据放入缓存中。
  • 读取地址 0x80 时,它不会在cache中,因此会发生linefill ,将 0x80 到 0x8F 的数据放入缓存中 - 在此过程中,会将地址 0x40 到 0x4F 的数据从cache中剔除。
  • 结果写入0x00。根据分配策略,这可能会导致又一次的linefill(注意是根据分配策略决定的)。在此过程中,地址 0x80 到 0x8F 的数据可能会再一次从cache中丢失。
  • 循环的每次迭代都会发生同样的事情,这导致我们的软件性能很差。因此,一般在处理器主要cache中不会使用直接映射cache。

组相联cache

ARM内核的主要cache一直使用组相联cache,因为前文我们已经提到过,这可以显著降低直接映射cache的颠簸问题,提高程序执行的性能和确定性

但是,组相联cache相比直接相联cache需要增加硬件复杂度和功耗,因为组相联cache在一次hit-miss检查中需要比较多个tag。

set-way

在组相联cache中,cache被分成许多大小相同的部分,称为way。然后相同的内存地址访问可以映射到特定set(index)的多个way中的一个,而不是映射到cacheline 。

在hit-miss check中,必须同时检查某个对应set的所有way。

在下图中,显示了一个2way的cache。地址 0x00(或 0x40 或 0x80)的数据可能会在2个way中某一个的第0行,注意不可能同时存在多个way中

b85315140365c0789c1f7819714fdef9.png

全相联cache

增加cache的关联度可以降低颠簸,最理想的cache是全相联cache,即任何主存访问地址可以映射到cache中的任何位置

一个组相联cache示例

63e3671ad02b3988b132e7636f0ee3df.png

上图是一个4way组相联的 32KB cache,每个cacheline具有 8个字。

cache的cacheline具有8个字(32 个字节),我们的cache有 4 way。32KB 除以 4(way数),再除以 32(每个cacheline中的字节数)得出每个way具有 256 行(set index)。

这意味着需要 8 比特来索引一条way内的set(比特 [12:5])。然后,使用地址的比特 [4:2] 从cacheline中的8个字中进行选择1个字,比特[1:0]选择具体的字节。最终,剩余的比特[31:13] 用作tag。

作者:验证哥布林
来源:芯片验证工程师
https://mp.weixin.qq.com/s/xH-kl0FHUai0KGnGU3eShg
https://mp.weixin.qq.com/s/tPhaH0vOjLj7DkFHJE_Z9Q
https://mp.weixin.qq.com/s/fKC98ovnyl1fm2O5WyIyNA

推荐阅读

更多数字IC设计技术干货等请关注数字芯片实验室专栏。添加极术小姐姐(微信:aijishu20)微信可申请加入IC设计交流群。
推荐阅读
关注数
12313
内容数
219
前瞻性的眼光,和持之以恒的学习~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息