ARM cache 分析

1 篇文章 0 订阅

为什么需要Cache?

从程序运行这个示例来进行解释,程序在运行时,先将执行程序从flash 加载到main memory, 然后CPU 从main memory 加载指令/数据到进行执行和计算。在不考虑cache 的情况下,整体架构可以描述为 

 程序需要从低速设备加载到高速CPU中运行,其中速度之差如下图:

 

CPU register的速度一般小于1ns,主存的速度一般是69ns左右。速度差异近百倍。当CPU试图从主存中load/store 操作时,由于主存的速度限制,CPU不得不等待这漫长的65ns时间。

如何解决上述问题:

  1. 提升 main memory 的速度
  2. 降低 CPU 速度
  3. 增加小而高速缓存

对于方法1当前 main memory 一般是 G 为单位,在提升速度的时候,又保持大容量,这将使得成本非常巨大;

对于方法2,这是个谬论;

增加小而高速的缓存,当前 sram 的速度基本可以和 CPU 一致,容量小的情况下成本是可以接受的。采用 cache 方案之后的程序加载流程如下:

 各级速度对比

Cache 架构

 上图是典型的哈佛 cache 架构,描述了CPU,cache 和 memory 的位置关系。参考

《ARM cortex-A series programmer's guide》

Cache 映射方式

系统加入 cache 之后,如何将 main memory 和 cache 映射起来?

cache 的映射方式

直接映射

                 参考《ARM cortex-A series programmer's guide》

加入 cache line 大小是 8bytes, cache 大小是 64 bytes,那么总共会有8个 cacheline. 对每个 cache 做标示,则 index 是从0 到 7.

索引 cacheline 需要 3 bit,使用地址低 bit[2:0] 表示

每个cacheline 的 index 使用 bit[5:3] 表示

那么, 0x0000 0000 和 0x0000 0040 都指向了 cacheline 0 类似这种,地址和 cache line 是一一对应的。这种情况下,比如 先访问 0x00,cache 中内容不存在,需要重新加载,此时又访问了内存地址 0x40, 因为也是索引 cache line 0, 虽然cache hit, 此时内容是不同的,因此需要flush 之后重新加载。如果反复在 0x00 和 0x40 之间切换,实际上造成了cache 颠簸,cache 并没有提升性能。

全相联

每个内存对应的cache line的位置不固定,可以映射到不同cache line。这种情况下需要花费大量时间来查找可用的 cache,代价也十分大

组相联

                        《ARM cortex-A series programmer's guide》 

组相连是对直接映射和全相连的一个折衷,将cache划成几路(way)和组(Set)进行管理。

先看几个cache 术语

如上图,一个cache就是一个sram,

Way(路):为了方便管理,我们将sram cache分成了若干个way(通常是4个),

Set(组): 然后又将每个way分成若干个line;每个way中,都对line进行编号,有index=1,2,3..n(index=1表示cache line的编号即line1,index=2表示line2), 我们将在不同way中,index相同的叫成set。

Tag: 所有的cacheline 都是唯一的,每一个都有一个tag

在cache管理中,最小的处理单元是cacheline即:

对于一个 大小为 16K, cacheline 是64bytes 的cache,假如

way: 4个,每个 way 大小是 4K

Set: 64个,需要 6bit 索引,使用对应地址的 bit[11:6] 来进行索引;

Offset: 用于索引 cacheline,总共需要 6bit,使用对应地址的 bit[5:0]索引;

假如某次操作检查cache 命中状态,会先根据bit[11:6]索引对应的Set,假设都是 cacheline N, 那么因为Way有4个,所以需要使用tag来比较落在哪个way中,如果tag 相同则认为命中,否则是miss。

这个时候引出了使用什么地址来索引 cache。

 

Cache 索引方式

歧义:同一个虚拟地址指向不同的物理地址

别名:不同虚拟地址指向同一个物理地址

VIVT

 index 和 tag 都是使用虚拟地址查找,不需要经过MMU硬件,因此硬件成本是最低的。但是软件维护成本是个灾难,首先同一个地址指向的是不同物理地址,但是在cache 使用时,又使用相同cache,这会带来异常巨大维护。

PIPT

使用PIPT不会有别名问题,因为不同虚拟地址最终对应的都是同一个物理地址,这样cache的使用都是通过物理地址来比对的,不会有别名问题。 

VIPT

 

这里使用虚拟地址作为 index 索引 set, 物理地址作为tag, 那么这种情况有没有别名问题?

如果 VI=PI, 那么是没有别名问题的。

如果VI != PI ,是会有别名问题的。

假如一个 page 是 4K, 那么在MMU映射时,低 12bit物理地址是和虚拟地址相同的,那么如果一个 cachesize/way 小于等于page, 那么 VI=PI,否则 VI != PI的。

Cache Policy

写操作时,

  1. 若 cache hit, 有两种方式:
  • write-back : 写入时写入 cache
  • write-through: 写入时同时写入 cache 和 main memory.
  1. 若 cache misses, 则:
  • write-allocate: 将data 写入 cache, 然后通过 flush 写入memory
  • 非 write-allocate: 直接写入 memory

读操作:

  1. cache hit: 直接读取
  2. cache miss:
  • read-through: 直接从 memory 中读取数据
  • read-allocate: 先从memory 读取数据到cache, 然后从cache 读取数据。

cache coherency:

解决cache 一致性可以通过:

  1. 使用 non-cacheable 或者某些情况下使用 write-through 方式
  2. 将系统 cache 禁掉
  3. 多核上,硬件上 MESI 机制保证cache一致性

Cache 问题处理思路

 

Cache 问题主要是基于上图的一个示意图来分析,常见的问题主要是 Cache 和 DDR 内容不一致导致的。

  1. ARM Core 向DDR 写入内容,在Cache 中命中,先写入 Cache, 然后导致Peripheral 读取的对应内容不一致,出现异常,ARM Core 写入之后需要 clean 相关cache
  2. Peripheral 向 DDR写入内容,ARM Core 读取对应DDR 地址在Cache中命中,出现 Cache中内容和 DDR内容不一致,此时需要peripheral 写入之后 invalidate.

注意: Cache 在 invalidate 时,如果对应 cacheline dirty, 是会先执行 clean之后再 invalidate.

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值