sync barrier - ceragon/LinuxDoc GitHub Wiki
用于指示编译器不要对代码进行指令重排序,或者说屏障之前的代码和屏障之后的代码不会穿插重排。
#define barrier() __asm__ __volatile__("": : :"memory")
- alternative: 选择宏,通过让 CPU 在运行时,根据支持的指令集来选择调用相应的指令。
- m/l/sfence: 新的屏障指令
- lock; addl $0,0(%%esp): 加锁,并对esp寄存器+0
#ifdef CONFIG_X86_32
#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
#else
#define mb() asm volatile("mfence":::"memory")
#define rmb() asm volatile("lfence":::"memory")
#define wmb() asm volatile("sfence" ::: "memory")
#endif
lock 后面需要接一个指令(例如 inc 或 xchg),指令满足以下条件:
- 该指令的操作目标必须是内存
- 一个指令涉及读取和修改两个操作
通过对这种指令+lock前缀,可以保证读和写内存这两个操作具有原子性.
MESI:在3级缓存架构的cpu中,所有对于内存的读写都需要先将内存值加载到三级缓存中。 在缓存行中有一个状态位,分为4中状态:
- I(invalid): 无效状态,当前缓存行所有值无效。
- E(exclusive): 排它状态,内存的副本被当前缓存行独占
- S(share): 多个核心共享内存的副本
- M(modified): 缓存行已修改,等待写回时同步回主存
MESI 保证了读或写操作的原子性。