aarch64体系结构与编程8--cache基本介绍
Opened this issue · 0 comments
cache内部构图
- 高速缓存行:高速缓存中最小的访问单元
- 索引(index)域:用于索引和查找是在高速缓存中的哪一行
- 标记(tag):高速缓存地址编码的一部分,通常是高速缓存地址的高位部分,用来判断高速缓存行缓存数据的地址是否和处理器寻址地址一致
- 偏移(offset):高速缓存行中的偏移。处理器可以按字(word)或者字节(Byte)来寻址高速缓存行的内容
- 组(set):相同索引域的高速缓存行组成一个组
- 路(way):在组相联的高速缓存中,高速缓存被分成大小相同的几个块
Cache映射方式 - 直接映射
当每个组只有一行高速缓存行时,称为直接映射高速缓存(direct-mapping)
例子:假设在下面的代码片段中,result、data1和data2分别指向0x00、0x40和0x80地址,它们都会使用同一个高速缓存行。
void add_array(int *data1, int *data2, int *result, int size)
{
int i;
for (i=0 ; i<size ; i++) {
result[i] = data1[i] + data2[i];
}
}
优点:命中率比较高,Cache存储空间利用率高。
缺点:访问相关存储器时,每次都要与全部内容比较,速度低,成本高,因而应用少
Cache映射方式 – 全关联
当cache只有一个组,即主存中只有一个地址与n个cache line对应,称为全关联.(只有一块cache)
也很容易出现缓存颠簸
Cache映射方式 –组相联
直接映射和全关联直接的做一个折中 - 组相联(set associative)
- 一个2路组相联的高速缓存为例,每一路包括4个高速缓存行,那么每个组有两个高速缓存行可以提供高速缓存行替换
- 减小高速缓存颠簸
如图,有2-way cacheline.缓存被替换的概率下降50%.
组相联实例
举个例子:32KB大小的4路组相联的cache,其中cache line为32字节,请画出cache的映射结构图
1.高速缓存行总大小为32KB,并且是4路(way),所以每一路大小为8KB: way_size = 32 / 4=8KB
2.高速缓存行大小为32字节,所以每一路包含的高速缓存行数量为:num_cache_line = 8KB / 32 = 256
上面这个图截取的programmer guide,图片不对,我修改了下.
物理高速缓存
虚拟高速缓存
- 虚拟高速缓存:处理器使用虚拟地址来寻址高速缓存
- 缺点:会引入不少问题:
- 重名(Aliasing)问题
- 同名(Homonyms)问题
重名 (Aliasing) 问题
- 在操作系统中,多个不同的虚拟地址有可能映射相同的物理地址。由于采用虚拟高速缓存架构,那么这些不同的虚拟地址会占用高速缓存中不同的高速缓存行,但是它们对应的是相同的物理地址
- 举个例子:VA1和VA2都映射到PA,在cache中有两个cache line缓存了VA1和VA2
当程序往VA1写入数据时,VA1对应的高速缓存行以及PA的内容会被更改,但是VA2还保存着旧数据。这样一个物理地址在虚拟高速缓存中就保存了两份数据,这样会产生歧义
同名(Homonyms)问题
- 相同的虚拟地址对应着不同的物理地址,因为操作系统中不同的进程会存在很多相同的虚拟地址,而这些相同的虚拟地址在经过MMU转换后得到不同的物理地址,这就产生了同名问题
- 同名问题最常见的地方是进程切换。当一个进程切换到另外一个进程时,新进程使用虚拟地址来访问高速缓存的话,新进程会访问到旧进程遗留下来的高速缓存,这些高速缓存数据对于新进程来说是错误和没用的。解决办法是在进程切换时把旧进程遗留下来的高速缓存都置为无效,这样就能保证新进程执行时得到一个干净的虚拟高速缓存
高速缓存分类
- VIVT(Virtual Index Virtual Tag):使用虚拟地址的索引域和虚拟地址的标记域,相当于是虚拟高速缓存
- PIPT(Physical Index Physical Tag):使用物理地址索引域和物理地址的标记域,相当于是物理高速缓存
- VIPT(Virtual Index Physical Tag):使用虚拟地址索引域和物理地址的标记域
VIPT工作过程
cache层级
多级cache处理流程
举例:LDR X0, [X1],加载x1地址的值到x0,假设x1地址是cachable的
Case 1:如果x1的值在L1 cache中,那么CPU直接从L1 cache获取了数据
Case 2:如果x1的值不在L1 cache中,而是在L2 cache中
(1) 如果L1 cache中没有空间,那么会淘汰一些cache line
(2) 数据从L2 cache line加载到L1 cache line
(3) CPU从L1 cache line中读取数据
Case 3:x1的值都不在L1和L2 cache中,但是在内存中
(1) 如果L1 cache和L2 cache中没有空间,那么会淘汰一些cache line
(2) 数据从内存中加载到L2和L1的cache line中
(3) CPU从L1 cache line中读取数据
多级cache的访问延迟
Cache的策略(Cache policies)
Cache相关的策略是在MMU页表中配置。只有Normal内存可以被cacheable
Cache策略包括:
- Cacheable/non-cacheable
- Cacheable细分:
- Read/write-allocate
- Write-Back cacheable、write-through cacheable
- Shareability
Cache分配策略:
- Write allocation: 当write miss的时候才分配一个新的cache line
- Read allocation:当read miss的时候才分配一个新的cache line
Cache回写策略:
- Write-back: 回写操作仅仅更新到cache,并没有马上更新会内存。(cache line is marked as dirty)
- Write through:回写操作会直接更新cache和内存
Write Back和Write Through
WT写直通模式
- 进行写操作时,数据同时写入当前的高速缓存、下一级高速缓存或主存储器中
- 直写模式可以降低高速缓存一致性的实现难度,其最大的缺点是消耗比较多的总线带宽
写直通模式:写数据的时候,直接写入到cache和内存中,不会把cache line设置为dirty.
ARM Cortex-A系列处理器把WT模式看成Non-cacheable
- The Cortex-A72 processor memory system treats all Write-Through pages as Non-cacheable
WB模式回写模式
- 在进行写操作时,数据直接写入当前高速缓存,而不会继续传递,当该高速缓存行被替换出去时,被改写的数据才会更新到下一级高速缓存或主存储器中。该策略增加了高速缓存一致性的实现难度,但是有效降低了总线带宽需求
- Cache line变成Dirty data
write-back模式:仅仅标记cacheline的状态位脏(dirty),当发生evicted或者clean/flush的时候,才把脏数据写到内存中
Inner and outer sharable
- Normal memory 可以设置inner或者outer shareability
- 怎么区分是inner或者outer,不同设计有不同的区分
- inner attributes 通常是CPU IP集成的caches
- outer attributes are exported on the bus
Point of Unification (PoU)和Point of Coherency (PoC)
PoU: 表示一个CPU中的指令cache,数据cache还有MMU,TLB等看到的是同一份的内存拷贝
- PoU for a PE,是说保证PE看到的I/D cache和MMU是同一份拷贝。大多数情况下,PoU是站在单核系统的角度来观察的
- PoU for inner share,意思是说在inner share里面的所有PE都能看到相同的一份拷贝
PoC:系统中所有的观察者例如DSP, GPU,CPU, DMA等都能看到同一份内存拷贝
PoU和PoC的区别
- PoC是系统一个概念,和系统配置相关
- 例如,Cortex-A53可以配置L2 cache和没有L2 cache,可能会影响PoU的范围
Cache维护
Cache的维护操作:
- 无效(Invalidate)整个高速缓存或者某个高速缓存行。高速缓存上的数据会被丢弃
- 清除(Clean)整个高速缓存或者某个高速缓存行。相应的高速缓存行会被标记为脏,数据会写回到下一级高速缓存中或者主存储器中
- 清零(Zero)操作
Cache管理的对象:
- ALL:整块高速缓存
- VA:某个虚拟地址
- Set/Way:特定的高速缓存行或者组和路
Cache管理的范围:
- PoC
- PoU
Shareability:
- inner
Cache的枚举(Cache discovery )
当我们在做cache指令管理的时候,你需要知道如下信息:
-
系统支持多少级的cache?
-
Cache line是多少?
-
每一级的cache,它的set和way是多少?
-
对于zero操作,我们需要知道多少data可以被zeroed?
-
Cache Level ID Register (CLIDR, CLIDR_EL1):列出有多少level的cache
-
Cache Type Register (CTR , CTR_EL0):cache line大小
-
sets and ways:需要访问两个寄存器来获取
- 告诉Cache Size Selection Register (CSSELR , CSSELR_EL1),要查询那个cache
- 从Cache Size ID Register (CCSIDR , CCSIDR_EL1)中读取相关信息
-
Data Cache Zero ID Register (DCZID_EL0)