笔记-各处理器乱序模型



处理器Load-LoadLoad-StoreStore-StoreStore-Load数据依赖
x86NNNY(简单理解:写可以异步)N

PowerPC

ARMv7(安卓/苹果)

YYYYN
ia64YYYYN

 

下文摘录自:

http://www.wowotech.net/kernel_synchronization/why-memory-barrier-2.html

 

 

(1) smp_mb(): “memory barrier” that orders both loads and stores. This means that loads and stores preceding the memory barrier will be committed to memory before any loads and stores following the memory barrier.对load和store都有效的全功能memory barrier,执行了该memory barrier指令的CPU可以保证smp_mb之前的load和store操作将先于该指令之后的load或者store操作被提交到存储系统。

(2) smp_rmb(): “read memory barrier” that orders only loads.只规定load操作的memory barrier。

(3) smp_wmb(): “write memory barrier” that orders only stores.只规定store操作的memory barrier。

(4) smp_read_barrier_depends() that forces subsequent operations that depend on prior operations to be ordered. This primitive is a no-op on all platforms except Alpha. 如果前后两个memory access有依赖关系(例如前一个的操作是取后一个要操作memory的地址),那么smp_read_barrier_depends()这个memory barrier原语可以用来规定这两个有依赖关系的内存操作顺序。当然,除了Alpha,在其他的CPU上,该原语都是空。

(5) mmiowb() that forces ordering on MMIO writes that are guarded by global spinlocks. This primitive is a no-op on all platforms on which the memory barriers in spinlocks already enforce MMIO ordering. The platforms with a 
non-no-op mmiowb() definition include some (but not all) IA64, FRV, MIPS, and SH systems. This primitive is relatively new, so relatively few drivers take advantage of it. mmiowb主要用于约束被spin lock保护的MMIO write操作顺序。当然,有些CPU architecture平台中,spinlock中的memory barrier操作已经保证了MMI的写入顺序,那么这个宏是空的。mmiowb是空的CPU architecture包括(但不限于)IA64, FRV, MIPS, and SH。这个原语比较新,因此在比较新的driver会使用它。

The smp_mb(), smp_rmb(), and smp_wmb() primitives also force the compiler to eschew any optimizations that would have the effect of reordering memory optimizations across the barriers. The smp_read_barrier_depends() primitive has a similar effect, but only on Alpha CPUs. See Section 14.2 for more information on use of these primitives.These primitives generate code only in SMP kernels, however, each also has a UP version (mb(), rmb(), wmb(), and read_barrier_depends(), respectively) that generate a memory barrier even in UP kernels. The smp_ versions should be used in most cases. However, these latter primitives are useful when writing drivers, because MMIO accesses must remain ordered even in UP kernels. In absence of memory-barrier instructions, both CPUs and compilers would happily rearrange these accesses, which at best would make the device act strangely, and could crash your kernel or, in some cases, even damage your hardware.

smp_mb(), smp_rmb(), 和 smp_wmb() 原语除了指导CPU的工作(规定cpu提交到到存储系统的操作顺序),它们对编译器也有作用(linux中的优化屏障barrier()),这些原语阻止了编译器为了优化而重排内存访问顺序。smp_read_barrier_depends有同样的效果,但是仅仅适用在Alpha处理器上。想要知道更多的关于这些原语使用的知识,请参考14.2章节。上面的这些smp_xxx的原语主要用在SMP的场合,在SMP的场景下会生成具体的memory barrier指令代码,在UP场合下,它们不会生成代码(仅仅是一个优化屏障而已)。smp_xxx的原语有对应的UP版本的memory barrier原语(mb(), rmb(), wmb(), 和read_barrier_depends()),这些UP版本的原语无论是SMP还是UP场合,都会生成具体的memory barrier指令代码。虽然大部分场景都是使用smp_xxx版本的memory barrier原语,但是,对于驱动工程师,由于需要规定MMIO的顺序(不仅适用SMP,也适用UP),因此,UP版本的memory barrier原语也经常使用。如果缺少了这些memory barrier原语,那么CPU和编译器都可以愉快的按照其自己的想法来对memory access顺序进行重排,而这样的行为轻则让设备行为异常,或者内核crash,重则造成硬件的损伤。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值