四平市建设局网站,网易企业邮箱密码忘记了怎么找回密码,深圳聘请做网站人员,wordpress 注册 模版文章目录 cpu缓存一致性缓存的出现#xff1a;多核之后带来的缓存一致性问题#xff0c;如何解决LOCK 指令#xff08;刚好可以实现上述的目标#xff09;LOCK 指令特性内存屏障特性编译器屏障的作用MESI协议为什么有了 MESI协议 还需要 内存屏障问题#xff1a;总结… 文章目录 cpu缓存一致性缓存的出现多核之后带来的缓存一致性问题如何解决LOCK 指令刚好可以实现上述的目标LOCK 指令特性内存屏障特性编译器屏障的作用MESI协议为什么有了 MESI协议 还需要 内存屏障问题总结附带 参考 cpu缓存一致性
缓存的出现
提高内存的访问速度时间、空间局部性指令、数据的预取
多核之后带来的缓存一致性问题如何解决 锁总线 MESI 协议总线嗅探机制 内存屏障
LOCK 指令刚好可以实现上述的目标
早期锁总线实现性能差 后期锁缓存实现Ringbus MESI协议硬件支持无需软件实现内存屏障
LOCK 指令特性
硬件层面提供 lfence、sfence、mfence 三个内存屏障以及一个可以实现相同效果的 lock 指令前缀一般lock都会加入读屏障保证后续代码可以读到别的cpu核心上的未回写的缓存数据而unlock都会加入写屏障将所有的未回写的缓存进行回写。
内存屏障特性
所有的CPU内存屏障封装都隐式包含了编译器屏障。只有内存屏障是无法保证缓存的同步的还需要MESI一致性协议的支持
编译器屏障的作用
防止编译乱序数据重新load缓存
MESI协议
保证了单条指令的在缓存上的读写的一致性MESI协议可以通过提供加入缓存带来的数据一致性问题但是会带来一些性能的消耗比如说缓存的伪共享MESI是强一致性强一致性必定会带来性能的损害
为什么有了 MESI协议 还需要 内存屏障
MESI是强一致性的比如需要等待写失效才能写入内存所以硬件又引入了store buffer还有invalid queue导致了有可能cpu 的乱序执行为了禁止这种乱序执行需要加入内存屏障但是这种乱序执行的前提是数据之间没有依赖性
问题 那如果当前访问的数据在寄存器上面呢 需要 用到 volatile指令强制从缓存中读取一次数据间接通过MESI协议能够访问到内存中的数据 那如果是多条指令的顺序性呢内存数据还在store buffer、invalid queue上面呢 需要用到 内存屏障的指令比如 x86 fence
总结
volatile指令的作用cpp的volatile和java的特性不一致 c volatile 的特性 禁止编译器的优化禁止编译器的代码的重排序强制从缓存中读取失效寄存器 java volatile 的特性是基于 LOCK 指令 实现的 在cpp的特性的基础之上实现了一个全屏障越过cpu的乱序执行、指令重排序等保证了数据的顺序一致性 缓存的一致性保证是通过 MESI 协议总线嗅探机制 内存屏障 实现的因此为什么说 尽管有了 CPU有缓存一致性协议MESI为什么JMM还需要volatile关键字主要是增加屏障的目的单靠MESI协议无法保证 整体顺序的一致性
附带
// (java 9) hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp
// java实现的内存屏障
inline void OrderAccess::loadload() { compiler_barrier(); }
inline void OrderAccess::storestore() { compiler_barrier(); }
inline void OrderAccess::loadstore() { compiler_barrier(); }
inline void OrderAccess::storeload() { fence(); }
inline void OrderAccess::acquire() { compiler_barrier(); }
inline void OrderAccess::release() { compiler_barrier(); }
inline void OrderAccess::fence() {if (os::is_MP()) {// always use locked addl since mfence is sometimes expensive
#ifdef AMD64__asm__ volatile (lock; addl 0,0(%%rsp) : : : cc, memory);
#else__asm__ volatile (lock; addl0,0(%%esp) : : : cc, memory);
#endif}compiler_barrier();
}参考
volatile也不过如此
C/C Volatile关键词深度剖析
既然CPU有缓存一致性协议MESI为什么JMM还需要volatile关键字