ARMv8-A编程指导之内存序(2)

2 Barriers

        ARM架构包含能够强制访问序和在特定点完成的barrier指令。在一些架构中,类似的命令称为fence。

        如果你写代码的地方顺序非常重要,看Appendix J7 Litmus Tests。

        ARM架构参考手册定义了某些重要术语,特别的,术语observe和must be observed。在典型的系统中,它定义了master的总线接口(比如,core或者GPU和内联)必须处理总线事务。仅master可以看到传输。所有的总线事务都是由master发起的。master发起事务的顺序没有必要与事务在slave设备上完成的顺序一样,因为事务可能被内联重排,若没有特别的强制。

        一个简单的方法来描述可见性:当我能读取你写的内容时我可以看到你写的内容,当我不再修改你读取的内容时,我看到你所读取的内容。这里提到的”我”和“你”为core和系统中的其他master。

        这里有架构提供的三种barrier指令:

ISB:这用于保证任何后续的指令都被取出,这样当前MMU配置检查了特权和访问。用于保证任何之前已执行的修改上下文的操作,如写系统控制寄存器,在ISB完成时候也完成。对于硬件来说,这意味着指令流水线被冲刷。典型的在内存管理中使用这个,cache管理,上下文切换代码,或在内存中代码被移除。

DMB: 这可以防止数据访问指令的重排会跨barrier指令。所有的数据访问,loads或stores,不能为指令取出,处理器在DMB之前发出的,在特定的shareability域对其他master都可见,这也在DMB之后的任何数据访问之前可见。

        比如:

LDR x0, [x1]  // 在STR之前需要被内存系统看见

DMB ISHLD

ADD x2, #1 // 可能在内存系统看到前后执行

LDR.

STR x3, [x4] // 在LDR后必须被内存系统可见

        它也保证了任何之前的数据或统一的cache维护操作在后续数据访问执行之前完成。

DC CSW, x5 // 通过组/路清除数据

LDR x0, [x1] // 数据cache清楚操作可能没有被本指令看到

DMB ISH

LDR x2, [x3] // 数据cache清除操作被本指令看到

Instruction

DSB:  这使用与DMB相同的顺序,只是会阻塞其他的指令,不仅是loads或stores,或两者,知道同步操作完成。这可以用于阻止SEV指令的执行,比如,这将向其他core发送信号表示有事件发生。它会等待直到所有cache,TLB和分支预测维护操作对特定的shareability domain已完成。

        比如:

DC ISW, x5 //操作必须在DSB完成之前完成

STR x0, [x1] //访问必须在DSB完成之前完成

DSB ISH

ADD x2, x2, #3 //只有在DSB完成后才执行

        从上述例子可以看出,DMB和DSB指令有一个参数指定barrier操作的访问类型,以及应用的shareability domain。

        下表列出了有用的选项。

选项

访问顺序

Shareability domain

OSHLD

Load-load, Load-store

Outer shareability

OSHST

Store-store

OSH

Any-any

NSHLD

Load-load, Load-store

Non-shareable

NSHST

Store-store

NSOSH

Any-any

ISHLD

Load-load, Load-store

Inner shareable

ISHST

Store-store

ISOSH

Any-any

LD

Load-load, Load-store

Full system

ST

Store-store

SY

Any-any

        访问顺序域指明了barrier应用于哪些访问。有三种选择。

Load-Load/Store: 这意味着barrier要求所有的loads在barrier之前完成但不要求store完成。barrier之后的Loads和stores以程序顺序必须等待barrier完成在执行。

Store-store: 这意味着barrier仅影响store访问而loads仍可以在barrier自由重排。

Any-any: 这意味着loads和stores必须在barrier之前完成。Barrier之后的loads和stores必须等待barrier完成再执行。

        barrier用于防止不安全的优化产生且强制一个特定的内存顺序。使用不必要的barrier指令可以减少软件性能。需要慎重考虑在特定情况下barrier是否有必要,若有必要,barrier使用正确。

        一个更不易察觉的影响为指令接口,数据接口和core的MMU表walk被认为是分开的观察者。这意味着你需要使用DSB指令来保证对一个接口的访问可以在不同的接口中被看到。

        如果你执行了一个数据cache清除和无效化操作,比如DCCVAU X0,你必须后面插入一个DSB指令,来保证后续页表walk,转换表项的修改,指令的获取,或内存中指令的更新,可以看到这个新的值。

        比如,考虑转换表的更新:

STR X0,[X1] //更新转换表

DSB ISHST //保证写已完成

TLBI VAE1IS, X2 //无效化TLB中修改的页表项

DSB ISH //保证TLB无效化完成

ISB //在该处理器上同步上下文

        DSB用于保证维护操作已完成且ISB保证这些操作的效果可以被接下来的指令看到。

        处理器可以在任何时候预测性的访问标记为normal的地址。因此当考虑是否需要barrier时,不要仅考虑load或store指令产生的明确访问。

2.1 one-way barriers

        AArch64增加了新的load和store指令携带了隐藏的barrier语义。这要求所有的load和store在隐藏barrier之前或之后以程序顺序访问被看见。

Load-Acquire(LDAR):在LDAR之后的所有loads和stores以程序顺序,与目标地址的shareability domain匹配,在LDAR之后被看见。

Store-Release(STLR):在STLR之前的所有loads和stores,与目标地址的shareability domain匹配陪,在STLR之前被看见。

        还有一些互斥的版本,LDAXR和STLXR。

        不像数据屏障指令,它需要一个qualifier来控制那些共享域看到屏障,LDAR和STLR指令使用访问地址的属性。

        LDAR指令保证在LDAR之后的任何内存访问仅在load-acquire之后被可见。Store-release保证了所有更早的内存访问在store-release可见之前被看见,同时store对能够同时存储cache中数据的系统的所有部分可见。

        上图显示了访问是如何在一个方向上跨过one-way barrier而不是在其他方向上。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值