2 cache控制器
Cache控制器为负责管理cache内存的硬件模块,它是以一种程序不可见的方式。它自动从主存中将代码或数据写到cache中。它从core中获取读写内存请求,并对cache内存或外部内存发起必要的行为。
当它接受到来自core的请求时,它必须检查请求的地址是否在cache中。这就是cache查找过程。它是通过将请求的地址位的子集与cache中tag值做比较。若匹配即命中,cache line被标记为有效,可以使用cache中的内存进行读或写。
当core请求某个地址的指令或数据时,在cache tag中没有匹配,或tag无效,cache没有命中,请求必须被传递到内存层次的下一级,如L2 cache或外部内存。它也会造成cache line的填充。同时请求的数据或指令被发送到core。这个过程是透明的且对软件开发者不可见。core不需要在使用数据前等待cache line填充的完成。cache控制器通常访问cache line中的critical word。比如,你发送一个加载指令,但在cache中没有命中,会触发cache line的填充,core首先取出包含请求的数据的部分cache line。这些critical数据被发送到core的流水线,同时cache硬件和外部总线接口然后在后台读取剩下的cache line。
3 cache策略
当一个cache line被分配为数据cache,cache策略描述了当store指令执行且在数据cache中被命中时应该如何做。
cache分配策略如下:
Write allocation(WA):
一个cache line在写未命中时分配。这意味着在处理器上执行store指令可能会导致突发读产生。对于cache line,在写发出前通过linefill来获取数据。cache包含整个cache line,它是加载的最小单元,即使你仅在cache line写单个byte。
Read allocation(RA)
一个cache line在读未命中时分配。
cache更新策略如下:
Write-back(WB):
写只更新cache且将cache line标识为脏。当cache line被回收或明确的清除时才更新外部的内存。
Write-through(WT)
写同时更新cache和外部内存系统,这不会标记cache line为脏。
数据读在cache中命中的行为在WT和WB cache模式中一样。
正常内存的cacheable属性可分为inner和outer属性。Inner和outer的分界线由实现决定的,这在Memory Ordering中最更详细的描述。通常,inner属性用于集成cache,outer属性用于外部cache使用的处理器内存总线。
正常内存可能被处理器预测性访问,这意味着它可以自动将数据加载到cache中,而无需程序员显示的请求特定的地址。这也在Memory Ordering中最更详细的描述。
但是它也可以让程序员提供暗示给core在将来那些数据可以被使用。ARMv8-A提供提前加载的暗示指令。它是由实现来定义是否cache支持预测和提前加载。下列指令有效:
- AArch64:PRFM PLDL1KEEP,[Xm, #imm]; 这表示提前从Xm+offset中加载到L1 cache中作为临时预取,这意味着数据可能被多次使用。
- AArch32:PLD Rm; 从Rm地址中提前加载数据到cache中
更普遍的,A64指令用于预取内存的有如下形式:
PRFM <prfop>, addr
这里,<prfop> <type><target><policy> | #uimm5
<type> PLD对加载做预取,PST对store做预取
<target> L1/L2/L3
<policy> 用于保留和临时预取的KEEP意味着正常分配在cache中;用于streaming或非临时预取的STRM意味着内存只使用一次
Uimm5 表示暗示被编码为5bit。它是可选的。