ARMv8系列 Cache / TLB
Cache: 存储经常访问的instruction和data
TLB: 存储经常访问的MMU的地址转换(VA->PA)
1.Cache
1.1 架构
每个CPU都有L1 Data Cache 和 L1 Instruction Cache
每数个CPU会组成一个cluster, cluster拥有一个L2 Cache, 数个CPU共用一个L2 Cache
数个cluster使用一个L3 Cache
接下来就是和总线连接,总线和DDR,SSD,device等进行连接
1.2原理
经典VIPT缓存体系架构
TLB和Cache关系:Cache依赖于TLB提供的物理地址来访问数据。如果TLB未命中,Cache也无法正确访问数据。
set(s) by index -> set
set 遍历 way by tag -> line (cache line是确定tag的way)
line by offset -> 对应数据
1.3 高速缓存映射方式
直接映射(每个内存地址只能映射到缓存中的一个固定位置)
全相联映射(每个内存地址可以映射到缓存中的任意位置)
组相联映射(缓存被分成多个组(Set),每个组包含多个路(Way)。每个内存地址映射到一个固定的组(Set),但可以在组内的任意路(Way)中存储数据)
1.4 Virtual Cache / Physical Cache / VIPT
1.4.1 P Cache: 当处理器查询MMU和TLB得到物理地址之后,使用物理地址去查询高速缓存。
缺点:处理器在查询MMU和TLB后才能访问高速缓存,增加了流水线的延迟
1.4.2 V Cache: 处理器使用虚拟地址来寻址高速缓存。
缺点:重名/同名问题
1.4.3 VIPT
VIVT(Virtual Index Virtual Tag):使用虚拟地址index和虚拟地址tag,相当于是虚拟高速缓存。(1.4.1)
PIPT(Physical Index Physical Tag):使用物理地址index和物理地址tag,相当于是物理高速缓存。(1.4.2)
VIPT(Virtual Index Physical Tag):使用虚拟地址index和物理地址tag。
1.5 虚拟高速缓存导致的重名/同名问题
1.5.1 重名
VA1和VA2都映射到PA,在cache中有两个cache line缓存了VA1和VA2。 当程序往VA1写入数据时,VA1对应的高速缓存行以及PA的内容会被更改,但是VA2还保存着旧数据。这样一个物理地址在虚拟 高速缓存中就保存了两份数据,这样会产生歧义。
1.5.2 同名
相同的虚拟地址对应着不同的物理地址,因为操作系统中不同的进程会存在很多相同的虚拟地址,而这些相同的虚拟地址在经
过MMU转换后得到不同的物理地址,这就产生了同名问题。
同名问题最常见的地方是进程切换。当一个进程切换到另外一个进程时,新进程使用虚拟地址来访问高速缓存的话,新进程会
访问到旧进程遗留下来的高速缓存,这些高速缓存数据对于新进程来说是错误和没用的。解决办法是在进程切换时把旧进程遗
留下来的高速缓存都置为无效,这样就能保证新进程执行时得到一个干净的虚拟高速缓存。
1.6 VIPT导致的重名问题
VIPT可以避免同名问题,VIVT是tag和index都是虚拟的,但是VIPT是p tag, v index. 由于物理地址不同,缓存中的标签也不同,就会映射到不同的物理地址
1.7 cache 策略
Cache的策略(Cache policies) 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和内存。
1.8 共享属性
inner share: L1 L2
outer share : L3
1.9 POC / POU
POC 站在全局角度
POU 站在处理器角度
参考P240
1.10 维护指令
无效(Invalidate)整个cache或者某个cache line。高速缓存上的数据会被丢弃。 清除(Clean)整个cache或者某个cache line。相应的cache line会被标记为脏,数据会写回到下一级高速缓存中或者主存储器中。 清零(Zero)操作。
2.Cache 一致性
原因:系统中各级cache都有不同的数据备份,例如每个CPU核心都有L1
cache一致性关注的是同一个数据在多个高速缓存和内存中的一致性问题,解决高速缓存一致性的方法主要是总线监听协议,例如MESI协议等
例子:
驱动中使用DMA(数据cache和内存不一致)
Self-modifying code(数据cache的数据可能比指令cache新)
修改了页表(TLB里保存的数据可能过时)
2.1 系统级别的cache一致性
ACE接口实现系统级别的cache一致性
MESI协议来维护多核cache一致性
2.2 MESI协议详见 P252
2.3 example
2.3.1 cache False sharing
定义:多个CPU同时访问一个cache line中的不同数据
解决办法:让多线程操作的数据处在不同的cache line, cacheline填充 或 cacheline对齐
2.3.2 cache DMA
2.3.3 自修改代码
L1I和L1D是分开的,前者只读,特殊情况下才能修改
比如,把要修改的instruction,加载到L1D, 这个时候程序(CPU)修改新instruction,L1D中缓存了最新的instruction
问题:此时旧指令再L1I中,新指令在L1D中
3 TLB
3.1 定义
把最新的MMU的地址转换结果(VA->PA)缓存到TLB中
3.2 别名/重名问题
没有别名问题,因为存的就是VA->PA的结果,cache存在别名问题是因为cache存的是数据,即使PA相同,但是data可能存在不同
重名问题,老的解决方案就是放弃老进程的TLB,从而Cache也要放弃。但是如果对于完全的TLB,相当于冷启动了,用ASID解决
3.3 ASID
ASID让每个TLB项包含一个ASID,用于表示每个进程的地址空间。不同于PID(这个是身份证),ASID专用于TLB查询
3.3.1 global TLB: 内核空间所有进程共享的地址空间
3.3.2 进程独有TLB:用户地址空间是每个进程独立的地址空间
#嵌入式##Linux内核##内核开发##嵌入式Linux#