arch-x86.h中对内存屏障的定义:
#define pg_memory_barrier_impl()
__asm__ __volatile__ ("lock; addl $0,0(%%rsp)" : : : "memory", "cc")
#endif
lock;addl是什么含义?
- lock后的所有写操作,会造成总线同步,也就是cpu store buffer会flush出,通过修改过的地址,使其他CPU对应的cacheline失效。
- 那么这个addl给rsp寄存器加0的操作(rsp堆栈指针指向volatile数据,去内存中取变量需要用rsp去找)虽然不会改变rsp的值,但会触发store buffer的flush动作,进而同步所有核心的cacheline数据。
- 最终的效果就是cacheline全部同步一遍,不会读到旧的值。
volatile修饰的值修改时,不会被编译器把变量装到寄存器中;如果不修饰,CPU可能会从寄存器中读取,也可能从内存中读取,两边并发读的结果可能会不一致。
(java的volatile可能自带asm(lock;addr)的功能,这里有差异)
区别volatile阻止编译器把变量塞到寄存器里面,如果到寄存器里面,读的时候直接拿寄存器的值完全不走stroe buffer和缓存了,再做memory_barrier同步cacheline的数据也没效果了。



