Cache Maintenance-关于cache 清除(invalidate)和清理(clean)操作的基础知识

ARMv8-A架构中的Cache操作:清除、清理与清空
本文详细介绍了ARMv8-A架构中关于Cache的三种操作:清除(invalidate)、清理(clean)和清空(zero),以及它们在不同场景下的应用。清除操作使数据失效,清理操作使数据与内存同步,清空操作则直接将缓存数据置零。文章还提到了指令格式和注意事项,包括如何针对虚拟地址或特定Set/Way进行操作,并指出在某些情况下,如地址映射改变或权限修改时,可能需要执行这些操作。最后,文章提醒读者注意指令执行顺序和缓存一致性问题。

目录

Cache相关的操作

清除操作-invalidate-使数据失效

清理操作-clean-使数据同步

清空操作-zero-清空数据

清理清除操作对象

ALL,所有

MVA或VA,虚拟地址

Set or Way,通过Set和way的编号

指令格式

注意事项


有时候,软件很有必要去clean或者invalidate 缓存,这种情况通常是:

  • 外部内存的内容已经被改变,而cache中还是以前的数据,所以很有必要移除cache中陈旧的数据。
  • MMU相关的活动,比如:
    • 改变了内存的访问权限
    • 改变了缓存策略(WB、WT等)
    • 改变了虚拟地址(VA)到物理地址(PA)的映射关系
  • 需要同步指令缓存(I-Cache)和数据缓存(D-Cache)

需要注意的是,ARMv8-A架构中并没有提供可以invalidate 整个cache的指令,如果软件层面必须invalidate 整个cache,必须考虑cache的几何结构,即逐个Set/Way的方式来遍历cache,进行invalidate操作。此外,处理器在reset或者初始化后,其cache将会自动被invalidate,除非控制其DBGL1RSTDISABLE 或者 L2RSTDISABLE两个pin脚。

Cache相关的操作

清除操作-invalidate-使数据失效

invalidate操作主要是针对 cache line中的valid bit(有效位)进行操作。通过对有效位进行清零,从而使cache line中的数据失效,达到清除数据的目的。比如在上电或者重置操作后,cache中的内容是未定义的,此时它的valid bit为0。

清理操作-clean-使数据同步

clean操作主要针对cache line 中的 dirty bit(脏位)

某个cache line中的dirty bit为1,说明该line中的数据与内存中的数据不一致,我们就可以对该cache line描述为变“脏”了。

清除cache或cache line意味着将标记为“脏”的cache line内容写入下一级缓存或主内存,并清除cache line中的脏位。这使得当前的cache line中的数据与下一级缓存,或主存中的的内容相同。此操作仅适用于写回策略(WB)的数据缓存(data-cache)。

清空操作-zero-清空数据

这将使缓存中的内存块归零,而无需首先从外域读取其内容。这仅适用于数据缓存。

对于上述操作,可以选择具体操作的对象:

清理清除操作对象

ALL,所有

清理清楚的对象可以是整个的cache,但这不适用于数据缓存(DC)和统一缓存(unified cache)。

MVA或VA,虚拟地址

清理清除与虚拟地址相关的cache line。

Set or Way,通过Set和way的编号

通过set和way的编号定位到具体的cache line,从而进行清除清理操作。

指令格式

<cache> <operation>{, <Xt>}

 

 

 对于VA操作,这些指令接收一个保存有虚拟地址的64位寄存器,对此地址没有对齐限制。

对于set/way操作,指令接收包含Set/Way/Level参数的64位寄存器,它的低32位遵从ARMv7架构的格式。

所有指令缓存维护指令都可以按照相对于其他指令缓存维护指令、数据缓存维护指令以及加载和存储的任何顺序执行,除非在指令之间执行DSB。
指定地址的数据缓存操作(DC ZVA除外)只有在指定相同地址时才能保证以相对的程序顺序执行。指定地址的操作按照相对于所有未指定地址的维护操作的程序顺序执行。

 前两条指令按顺序执行,因为它们引用相同的地址。但是,最终指令可能会相对于前面的操作重新排序,因为它引用了不同的地址。

注意事项

AArch32的DCIMVAC指令以及AArch64的DC IVAC虽然是对一个虚拟地址VA进行invalidate操作,但是如果该地址上的数据在整个cluster里是dirty的,那么会自动在invalidate之前进行clean操作。

DCISW 和DCCSW,DC ISW 以及DC CSW指令,对set/way操作时,都会进行clean和invalidate操作。HCR.SWIO 以及HCR_EL2.SWIO的值对其无影响
 

在 Go 语言中,按位清除运算符 `&^` 是一种特殊的按位运算符,用于将某个整数中的特定位设置为 0,而其他位保持不变。它结合了按位与(`&`)按位非(`^`)操作的特性,可以高效地清除某些特定的标志位。 ### 按位清除运算符的工作原理 表达式 `a &^= b` 等价于 `a = a &^ b`,其含义是将 `a` 与 `b` 的按位非结果进行按位与运算。换句话说,对于 `b` 中为 1 的每一位,`a` 中对应的位将被设置为 0;而 `b` 中为 0 的位则保持 `a` 中的原始值不变。 ### 使用示例 下面是一个使用 `&^` 运算符的示例,演示如何清除一个整数中的某些特定位: ```go package main import "fmt" func main() { var a uint8 = 0b10101010 // 二进制表示 var b uint8 = 0b00001111 // 清除低四位 a &^= b // 清除 a 中与 b 中为 1 的对应位 fmt.Printf("结果为: %08b\n", a) // 输出结果为: 10100000 } ``` 在这个例子中,变量 `a` 的初始值为 `0b10101010`,而 `b` 的值为 `0b00001111`,表示我们希望清除 `a` 的低四位。执行 `a &^= b` 后,`a` 的低四位被设置为 0,最终结果为 `0b10100000`。 ### 与按位与按位非的等价操作 上述操作等价于以下表达式: ```go a = a & (^b) ``` 其中,`^b` 表示对 `b` 进行按位取反操作,然后将结果与 `a` 进行按位与运算。这种方式可以达到相同的效果,但使用 `&^` 可以简化代码并提高可读性。 ### 应用场景 - **标志位管理**:在系统编程中,常常使用整数的某些位表示特定的状态或标志。通过 `&^` 可以安全地清除不需要的标志位,而不影响其他状态。 - **性能优化**:在某些对性能敏感的场景中,使用位运算可以减少内存访问计算开销,`&^` 提供了一种高效的清除位的方式。 - **数据压缩**:在数据压缩算法中,经常需要对二进制位进行精细操作,`&^` 可以帮助快速调整位模式。 ### 总结 按位清除运算符 `&^` 是一种非常实用的工具,尤其适用于需要对整数的某些位进行清除操作的场景。它不仅简化了代码,还提高了可读性执行效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SOC罗三炮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值