jason--liu/Blog

aarch64体系结构与编程8--cache基本介绍

Opened this issue · 0 comments

cache内部构图

image

  • 高速缓存行:高速缓存中最小的访问单元
  • 索引(index)域:用于索引和查找是在高速缓存中的哪一行
  • 标记(tag):高速缓存地址编码的一部分,通常是高速缓存地址的高位部分,用来判断高速缓存行缓存数据的地址是否和处理器寻址地址一致
  • 偏移(offset):高速缓存行中的偏移。处理器可以按字(word)或者字节(Byte)来寻址高速缓存行的内容
  • 组(set):相同索引域的高速缓存行组成一个组
  • 路(way):在组相联的高速缓存中,高速缓存被分成大小相同的几个块

Cache映射方式 - 直接映射

当每个组只有一行高速缓存行时,称为直接映射高速缓存(direct-mapping)
image
例子:假设在下面的代码片段中,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)
image
也很容易出现缓存颠簸

Cache映射方式 –组相联

直接映射和全关联直接的做一个折中 - 组相联(set associative)

  • 一个2路组相联的高速缓存为例,每一路包括4个高速缓存行,那么每个组有两个高速缓存行可以提供高速缓存行替换
  • 减小高速缓存颠簸

image
如图,有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
image
上面这个图截取的programmer guide,图片不对,我修改了下.

物理高速缓存

  • 物理高速缓存:当处理器查询MMU和TLB得到物理地址之后,使用物理地址去查询高速缓存
  • 缺点:处理器在查询MMU和TLB后才能访问高速缓存,增加了流水线的延迟
    image

虚拟高速缓存

  • 虚拟高速缓存:处理器使用虚拟地址来寻址高速缓存
  • 缺点:会引入不少问题:
    • 重名(Aliasing)问题
    • 同名(Homonyms)问题

image

重名 (Aliasing) 问题

  • 在操作系统中,多个不同的虚拟地址有可能映射相同的物理地址。由于采用虚拟高速缓存架构,那么这些不同的虚拟地址会占用高速缓存中不同的高速缓存行,但是它们对应的是相同的物理地址
  • 举个例子:VA1和VA2都映射到PA,在cache中有两个cache line缓存了VA1和VA2
    当程序往VA1写入数据时,VA1对应的高速缓存行以及PA的内容会被更改,但是VA2还保存着旧数据。这样一个物理地址在虚拟高速缓存中就保存了两份数据,这样会产生歧义

image

同名(Homonyms)问题

  • 相同的虚拟地址对应着不同的物理地址,因为操作系统中不同的进程会存在很多相同的虚拟地址,而这些相同的虚拟地址在经过MMU转换后得到不同的物理地址,这就产生了同名问题
  • 同名问题最常见的地方是进程切换。当一个进程切换到另外一个进程时,新进程使用虚拟地址来访问高速缓存的话,新进程会访问到旧进程遗留下来的高速缓存,这些高速缓存数据对于新进程来说是错误和没用的。解决办法是在进程切换时把旧进程遗留下来的高速缓存都置为无效,这样就能保证新进程执行时得到一个干净的虚拟高速缓存

高速缓存分类

  • VIVT(Virtual Index Virtual Tag):使用虚拟地址的索引域和虚拟地址的标记域,相当于是虚拟高速缓存
  • PIPT(Physical Index Physical Tag):使用物理地址索引域和物理地址的标记域,相当于是物理高速缓存
  • VIPT(Virtual Index Physical Tag):使用虚拟地址索引域和物理地址的标记域

VIPT工作过程

image
VIPT别名问题
如下图所示
image

cache层级

两级的cache系统
image
三级的cache系统
image

多级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的访问延迟

image

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写直通模式

  • 进行写操作时,数据同时写入当前的高速缓存、下一级高速缓存或主存储器中
  • 直写模式可以降低高速缓存一致性的实现难度,其最大的缺点是消耗比较多的总线带宽

image
写直通模式:写数据的时候,直接写入到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

image
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

image

image

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都能看到相同的一份拷贝

image

PoC:系统中所有的观察者例如DSP, GPU,CPU, DMA等都能看到同一份内存拷贝
image
PoU和PoC的区别

  • PoC是系统一个概念,和系统配置相关
  • 例如,Cortex-A53可以配置L2 cache和没有L2 cache,可能会影响PoU的范围

image

Cache维护

Cache的维护操作:

  • 无效(Invalidate)整个高速缓存或者某个高速缓存行。高速缓存上的数据会被丢弃
  • 清除(Clean)整个高速缓存或者某个高速缓存行。相应的高速缓存行会被标记为脏,数据会写回到下一级高速缓存中或者主存储器中
  • 清零(Zero)操作

Cache管理的对象:

  • ALL:整块高速缓存
  • VA:某个虚拟地址
  • Set/Way:特定的高速缓存行或者组和路

Cache管理的范围:

  • PoC
  • PoU

Shareability:

  • inner

cache指令格式
image
image
image

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)