volatile关键字的深入理解


volatile关键字的深入理解

问题引起的缘由:硬件层面的优化带来的共享数据a可见性问题

由于CUP/内存/IO/磁盘三者之间的处理速度的差异引发的优化,CPU进行数据运算时需要存取内存中的数据,但他们之间的速度差异很悬殊;1、第一步优化是引入了高速缓存,分别L1/L2/L3缓存(速度逐级递减),而每个CPU都有自己的缓存(相当于L1),而多个CPU在访问共享资源时,会出现数据安全性问题,及CPU1改了某个共享资源a的值时,没有及时同步到主内存,而CUP2在计算a的值时不是拿的最新数据(即缓存一致性问题)。2、因此,这时又引入缓存一致性协议(X86架构用的MESI)【有四种状态...】(缓存行锁,锁的粒度小,只对共享数据进行加锁),通过缓存一致性协议来相互通知到各个CPU中缓存行a的值是不是需要重新到主内存 获取(L2->L3->主内存),但缓存一致性协议会存在一个通信延迟问题,在这中间会存在CPU阻塞的时间片段,这也是CPU资源的浪费,那又怎么办呢?3、优秀的工程师又引入了一个storebuffer来实现异步操作,进而进一步进行CPU资源的优化利用,即在改变共享变量a的值之,不需要等待通信结果,可以直接运行下面的程序指令;但这又会引发另一个问题,指令重排序问题(就是在两个CPU在执行某些场景的代码时,a变量为来得及同步,其他CPU就使用了a变量的值,类似于代码乱序执行),而这个问题是在硬件层面无法解决的问题,因为在硬件层面不知道软件层面何时需要进行这样的优化,因此会留有一个口子给软件应用开发者去使用,即CPU层面提供了指令->内存屏障(读屏障、写屏障、全屏障),加了这个屏障之后,相当于屏蔽了storebuffer的优化(强制性将storebuffer通知其他CPU的缓存行,或者说去除了storebuffer的优化?),即使得a共享变量的可见性。而映射在java层面,则是提供volatile等关键字来进行加内存屏障的操作。

疑问:
1、内存屏障是相当于去除storebuffer的优化,还是指的去除其他哪些优化?
   
 

猜你喜欢

转载自blog.csdn.net/qq_36336332/article/details/109375645