内存屏障
最近在研究lock free设计的时候,看到了内存屏障的概念。之前虽然也看到过,但是没有深入探究过。
所以花了两天的时间好好整理了一下内存屏障的知识。
-
内存屏障:rmb(), wmb(), mb()。
很多地方说是防止cpu指令重排。我研究发现其实并不是。在SMP系统中一个数据的存储和操作可能不在一个cpu核上,比如int a 存储在cpu0 cache,但是a++计算运行在cpu1。这就需要cpu0 cache和cpu1 cache之间的数据通信。为了保证在多处理器的环境下cache仍然一致,需要一种协议来防止数据不一致和丢失。目前常用的协议是MESI协议。虽然该协议可以保证数据的一致性,但是在某种情况下并不高效。CPU硬件设计为了提高指令的执行速度,增设了两个缓冲区(store buffer, invalidate queue)。这两个缓冲区是为了避免cpu在某些情况下不必要的等待,但是也同时带来了cpu cache的同步问题。所以只是从现象上来看像是指令重排。store buffer会导致写不同步,invalidate queue会导致读不同步。rmb()是让读之前处理完invalidate queue的read invalidate消息。wmb()是保证写store buffer之前把store buffer更新到cache。
参考:https://blog.csdn.net/chen19870707/article/details/39896655 -
优化屏障:barrier()
该原语保证编译程序不会混淆元语操作前后的汇编语言指令。优化屏障即barrier(),翻译成汇编就是asm volatile("":::“memory”)。
#define barrier() __asm__ __volatile__("": : :"memory")
在单核cpu系统中,使用barrier,防止编译器对内存访问的优化。
在SMP系统中,使用mb。
#ifdef CONFIG_SMP
#define smp_mb() mb()
#define smp_rmb() rmb()
#define smp_wmb() wmb()
#else
#define smp_mb() barrier()
#define smp_rmb() barrier()
#define smp_wmb() barrier()
#endif
总结:现在大多环境都是SMP系统,所以无需多区分内存屏障和优化屏障的概念。
而且为了便于理解,把内存屏障理解成为了解决代码乱序执行的问题也可以。
个人理解,如果错误请多多指正。