关于memory barrier/memory ordering 的笔记和总结(2)



             Memory ordering

Memory ordering用来描述系统中的processor对内存的操作如何对其它processor可见(可见的定义见前面的描述)。同时需要说明的是,大多数文献都采用reorder这个表达方式,是从执行等价的角度来描述的:比如P1上执行两个写操作WRITE(A)WRITE(B),如果对于观察者P2来说P1|WRITE(B)先于P2|WRITE(A)可见,那么就可以认为P1的写操作发生了reorder。对读操作也是类似的。

影响memoryordering的因素很多,包括:

  1. 体系结构,X86ARMmemory ordering就截然不同;

  2. 内存的类型,体系结构一般都会定义若干种内存类型,不同的内存类型有不同的memoryordering,比如X86分为Strong Uncacheable (UC)Uncacheable (UC-)Write Combining (WC)Write Through (WT)Write Back (WB)Write Protected (WP),而ARM的内存类型用memory typememory attribute来描述,不同的内存类型通常对应了不同的用途(具体情况见对应的厂商文档)。本文描述的是一般情况,也就是不做特殊处理,直接通过内存分配接口分配到的内存,也就是X86WB类型,ARMShareable Normal memory

  3. 具体的指令,比如INTELREP MOVSBREP STOSBmemory ordering就和一般的mov指令不一样。除非特别说明,而本文描述的是普通的内存访问指令,通常是C语言的赋值语句对应的汇编指令。

和前面描述SC的时候一样,XYZ表示变量,初始值都为0P1 P2表示processorR(X)=1表示从X中读到了值1W(X)=1表示向X中写入了值1P1|R(X)=1表示P1执行R(X)=1。符号A->B表示动作A先于动作B发生。

         X86memory ordering

X86memory ordering属于strong order,其与SC的要求接近,在大多数典型场景,没有必要使用memory barrier指令。即使是和外设的DMA操作共享的内存,X86也能通过bus snoop完成强顺序保证(查看linux内核分配一致性内存的接口dma_alloc_coherent,你会发现尼玛就是分配内存咯,并没有设置页表的PWT/PCD标识,也没有设置Memory type range registers(MTRRs))

                       普通内存操作

X86实现的memory ordering比较接近SC的要求,其违反SC的场景是:读操作可能和按照program order中在前面的对不同地址的写操作发生reorder,也就是读操作先于program order在其前面的对其他地址的写操作对外生效。注意:这里仅限于对不同地址的读和写。

也就是以下执行在X86上是可以发生的,但是并不满足SC的要求:

P1: W(X)=1R(Y)=0

P2: W(Y)=1R(X)=0

本例子明显不符合SC的要求,因为如果P1|R(Y)=0,那么必然有P1|R(Y)=0 –> P2|W(Y)=1

结合SC按照program order生效的要求,很容易得到P1|W(X)=1 -> P2|R(X)=0的悖论。

X86允许读操作先于按照program order在其前面的写操作对外生效,P1|W(X)=1 -> P1|R(Y)=0不一定成立,使得上面的序列在X86上变得合法。

 

以上执行序列可以看成是X86write buffer对程序员的体现,write bufferCPU上的一个部件,当一个写操作由于种种原因不能立即放到cache/内存中的时候,CPU可以先把它放到本CPUwrite buffer中,后续再刷新到内存中,这个write buffer只对本CPU可见。这就造成对一个地址的写操作在本 CPU看来已经完成,但是对其它CPU还不可见,而CPU继续执行后续的读操作,在其它CPU看起来,就造成了读和先前的写发生了reorder

                       Memory barrier指令

X86memory barrier指令包括lfence sfence mfence,这些指令通常在使用内存模型(比如Write Combining的操作),特殊的指令(REP MOVSB REP STOSB)才需要关注。

  1. lfence

    lfence确保program order在其前面的读不会和program order在其后面的读和写发生reorder,也就是lfence前面的读操作总是比lfence后面的读操作和写操作先生效。

  2. sfence

    sfence确保program order在其前面的写不会和program order在其后面的写发生reorder,也就是sfence前面的写操作总是比sfence后面的写操作先生效

  3. mfence

    mfence确保program order在其前面的写和写不会和program order在其后面的读和写发生reorder,也就是sfence前面的读操作和写操作总是比sfence后面的读操作和写操作先生效

                       隐含的memor barrier指令

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值