// 内存屏障
内存屏障是为了处理 乱序重排导致不同核之间的关联数据、指令操作。
乱序操作主要是缓存等其他硬件机制导致的memory数据、指令不一致。
缓存分为:数据cache、指令cache、指令流水线,所以内存屏障分为数据屏障、指令屏障。
指令同步屏障(ISB):它会清洗流水线,以保证所有它前面的指令都执行完毕之后,才执行它后面的指令
// 举例:更改ASID 、 切换TLB 、分支预测维护操作、修改 CP15 寄存器,导致将要执行的代码发生变化,如果不使用屏障,会出现乱序后先执行无效的代码
数据内存屏障(DMB):当所有在它前面的存储器访问操作都执行完毕后,才提交(commit)在它后面的存储器访问操作
数据内存屏障保证在指定域中的指令之前的显式内存访问/操作(包括加载或存储)早于指令之后的存储器访问/操作
// 举例:如果需要读取内存数据,并无效cache。需要使用DMB隔开,否则指令乱序后,还未读取cache中的数据,cache就已经被清除了
数据同步屏障(DSB):所有在它前面的存储器访问操作都执行完毕后,才执行在它后面的指令
数据同步屏障在指定域中的指令之前的数据存储访问/操作完成后才执行后面的指令。
// 举例:此指令前的显式内存访问、所有cache、分支预测和 TLB 维护操作全部完成后才能继续执行。
// 内存域:
1)非共享(Non-shareable)域
处于这个域中的内存只由当前CPU核访问,既然只能自己访问,那当然不用考虑跟系统中的其它模块,如其它CPU核或其它设备之间的数据同步问题。所以,如果一个内存区域是非共享的,系统中没有任何硬件会保证其缓存一致性。如果一不小心共享出去了,别的CPU核可以访问了,那必须由软件自己来保证其一致性。
2)内部共享(Inner Shareable)域
处于这个域中的内存可以由系统中的多个模块同时访问,并且系统硬件保证对于这段内存,对于处于同一个内部共享域中的所有模块,保证缓存一致性。
一个系统中可以同时存在多个内部共享域,对一个内部共享域做出的操作不会影响另外一个内部共享域。
3)外部共享(Outer Shareable)域
处于这个域中的内存也可以由系统中的多个模块同时访问,并且系统硬件保证对于这段内存,对于处于同一个外部共享域中的所有模块,保证缓存一致性。外部共享域可以包含一个或多个内部共享域,但是一个内部共享域只能属于一个外部共享域,不能被多个外部共享域共享。
对一个外部共享域做出的操作会影响到其包含的所有的内部共享域。
4)全系统共享(Full System)域
对内存的修改可以被系统中的所有模块都感知到。
// option:
OSHLD Load - Load, Load - Store 外部共享域
OSHST Store - Store 外部共享域
OSH Any - Any 外部共享域
NSHLD Load - Load, Load - Store 非共享域
NSHST Store - Store 非共享域
NSH Any - Any 非共享域
ISHLD Load - Load, Load - Store 内部共享域
ISHST Store - Store 内部共享域
ISH Any - Any 内部共享域
LD Load - Load, Load - Store 全系统共享域
ST Store - Store 全系统共享域
SY Any - Any 全系统共享域