作为一个编程人员
我们需要知道
1.当前芯片有什么cache配置
1.0 cache 当前配置
CCSIDR // MRC p15, 1, <Rt>, c0, c0, 0
CLIDR // MRC p15, 1, <Rt>, c0, c0, 1
CSSELR // MCR p15, 2, <Rt>, c0, c0, 0
CTR // MRC p15, 0, <Rt>, c0, c0, 1// 目前支持七级cache// 但一般配置为 2级别// L1 icache 32KB/48KB L1 dcache 32KB// L2 unified cache 2MB1.1 几级cache
指令cache L1
数据cache L1
unified cache L2 L3
1.2 如何区分arm 中的 outer/inner
The terms Inner and Outer refer to levels of caches that might be built in a system.
Inner refers to the innermost caches, including Level 1. Inner always includes L1.
Outer refers to the outermost caches.
The boundary between Inner and Outer caches is defined in the implementation of a cached system.
CLIDR 寄存器中的 LoUIS 定义了 outer/inner 的界限
1.3 cache 术语
1.3.1 cache line
tag(Valid status+ addr_high_bits)&data(data + dirty status)
data 中的data 字节数 为 cache 大小
很多个 cache line 是 tag array 和 data array 构成的
tag也是cache的一部分,但是我们谈到cache size的时候并不考虑tag占用的内存部分
举个例子,MESI在实现的时候, Valid status 和 dirty status 为MESI的值
1.3.2addr(phy&virt)tag(addr_high_bits)+index(in data array)+offset(in data)1.3.2 索引过程
1.3.2.1 由"addr中的index" 索引到 (SET,组)"cache line 中的 data array 中的 某个data"(A)(如果有N路,则1个SET对应到N个data)1.3.2.21个SET对应的N个"某个data对应的tag"中的 addr_high_bits 与 addr中的addr_high_bits 比较 ,如果有一路相等 . 且 Valid status =1, 则 命中
1.2.2.3 命中后, 看 data 中的 "dirty status", 如果为0,说明cache是干净的
1.2.2.4 干净时, 这个data 中包含了 "addr" 对应的数据,该数据 offset 从 "addr" 的 第 offset 个 Byte 开始.1.2.3.5 用 offset(按数组下标)索引 "某个data" 中的数据,得到的数据就是 "addr" 对应的 "value"1.3.2 索引过程中的 addr // https://zhuanlan.zhihu.com/p/107096130
根据 addr中的 (Tag的虚实 Index的虚实) 分类
PIPT // 一路大小大于4KB,一般采用PIPT方式,也不排除VIPT方式,这就需要操作系统多操点心了
PIVT // 不存在
VIVT // Cache问题太多,软件维护成本过高,是最难管理的高速缓存。所以现在基本只存在历史的文章中
VIPT // 一路的大小小于等于4KB,一般硬件采用VIPT方式,因为这样相当于PIPT1.4 cache 组织 // way数 越大, cache 颠簸越少1.1 直接映射缓存
// 有cache颠簸 cache thrashing// set数 为 cache_size/cache_line_size// way数 为 11.2 N路组相连缓存(N-way set associative cache)//N >=2 常见的为 2 4 8 16// 降低cache颠簸 cache thrashing// set数 为 cache_size/cache_line_size/N// way数 为 N1.3 全相连缓存(Full associative cache)// 最大限度降低cache颠簸 cache thrashing,硬件成本上也是更高// set数 为 1// way数 为 cache_size/cache_line_size1.5 cache 如何计算
根据 1(cache size)2(路数(N-way),假设为4路,4)3(cache line 大小)4(地址bit数)
假设
cache_size =32KB
N =4
cache_line_size =32Bytes
addr_bits =48
计算 : addr中的(tag&index&offset)&cache_line_array_number&set_number
注意 : cache_size 的值 仅仅包括 所有 cache line 的 大小,不包括 tag+V
注意 :tag(不是addr中的tag,而不是cache中的tag)也是cache的一部分,但是我们谈到cache size的时候并不考虑tag占用的内存部分.
注意 : 该 addr 由 三个部分组成,从高到低依次是 tag index offset
1.
offset_size =log2(cache_line_size)=5
offset =[(offset_size-1):0]=[4:0]2.
set_number = cache_line_array_number == cache_size/N/cache_line_size
=32*1024B /4/32B
=2563.
index_size =log2(set_number)=log2(256)=8
index =[(offset_size+index_size):offset_size]=[(4+8):5]=[12:5]4.
tag =[(addr_bits-1):(offset_size+index_size+1)]=[(48-1):(4+8+1)]=[47:13]2.cache的隐式操作及如何控制(cache策略)2.1 什么时候从 memory 加载数据到cache //Cache分配策略(Cache allocation policy)2.1.1 读分配(read allocation)2.1.2 写分配(write allocation)2.2 什么时候从 cache(write buffer) 写到 memory //Cache更新策略(Cache update policy)2.2.1 写直通(write through)2.2.2 写回(write back)2.3 cache满的时候,有新的行要进入,则要选择一个cache line 去丢弃 //替换策略
轮转法
伪随机替换法
最近最少使用法
2.4 如何和页表内容结合去动作
2.5 写cpu0 缓存行后,硬件利用什么机制更新cpu1的缓存行
2.5.1 写更新(write update)2.5.2 写无效(write invalidate)3. cache controller
高速缓存控制器是一个硬件块,负责管理高速缓存内存
其运行过程对程序来说基本上是不可见的。
但是我们可以从软件角度来控制 cache line 的内容,这些操作就是 Cache maintenance operations
4.Cache maintenance operations
4.1 on/off
4.2 lockdown
4.3 operations
clean/invalidate/flush(也叫 clean and invalidate)
By MVA/setway/all
By MVA的问题
当要 清理 某个地址对应的 cache行 时,根据cache层级 我们可以有很多种 操作层次
MVA
PoC // PoC = to Point of Coherence
PoU // PoU = to Point of Unification
IS //IS = Inner Shareable.
PE
4.4 何时做这些操作
PoC & PoU
PoC & PoU
PoC & PoU
是内存等级中的一个level,例如PoC 可以是内存 , PoU 可以是L2 cache
Point of Coherency(PoC).
For a particular address, the PoC is the point at which all
observers,for example, cores, DSPs, or DMA engines, that can access memory, are
guaranteed to see the same copy of a memory location.
Typically, this is the main external system memory.
PoC是一个内存等级
在这个等级上,"所有可以访问内存的观察者(例如,内核、DSP或DMA引擎)"
以某个特定地址 来索引, 都能看到同一个值。
Point of Unification(PoU).
The PoU for a core is the point at which the instruction and
data caches and translation table walks of the core are guaranteed to see the same copy of
a memory location.
For example, a unified level 2 cache would be the point of unification
in a system with Harvard level 1 caches and a TLB for caching translation table entries.
If no external cache is present, main memory would be the Point of Unification.
PoU是一个内存等级
分为两种
PoU for PE
在这个等级上,"core的icache dcache以及TLB"
以某个特定地址 来索引, 都能看到同一个值。
PoU for Inner Shareable
在这个等级上,"inner 内 的所有观察者"
以某个特定地址 来索引, 都能看到同一个值。
LoC & LoUU & LoUIS
CLIDR 的一些字段
LoC
Level of coherence
此字段定义在清除或失效到一致性点时必须清除或失效的最后一级缓存。对应 PoC
LoC值是缓存级别,因此,例如,如果LoC包含值3,则
clean到一致点操作需要clean1级、2级和3级缓存。
不用clean 4级缓存
LoUU
Level of unification, uniprocessor
该字段定义了在处理器clean 到 PoU for PE 时必须清洗或失效的最后一级缓存。
其他同LoC
LoUIS
Level of unification, Inner Shareable
此字段仅定义为多处理扩展的一部分。如果实现不包括多处理扩展,则此字段为RAZ。
该字段定义了在clean 到 PoU for Inner Shareable 时必须清洗或失效的最后一级缓存。
PoC & PoU 有什么用呢?
有一些 Cache maintenance operations 是 通过 all 或者 MVA 索引的
那么他们他们的操作范围(cache等级)有一些限制的,分为3类
PoC/PoU/PoU,IS
如果 操作是clean By MVA
范围是 PoC , 对应 LoC ,假设LoC 为 3, 则代表 如果 clean MVA 命中的 L1/L2/L3 cache line
范围是 PoU , 对应 LoUU ,假设LoUU 为 2, 则代表 如果 clean MVA 命中的 L1/L2 cache line
范围是 PoU,IS , 对应 LoUIS,假设LoUIS为 1, 则代表 如果 clean MVA 命中的 L1 cache line