我关于volatile JMM MESI的一些思考

volatile这个关键字是用来保证变量在多线程并发的时候的可见性的,顺便防止指令重排。

这大家都知道。
先放结论!

所以jvm使用lock前缀指令 利用了mesi协议 去实现了JMM层面的可见性重排序功能。

接下来就是我东抄西抄 东看西看之后的一些想法。

cpu的缓存

cpu的运算速度是相当快的,单位是以时间周期来计算的。

此处补一下时钟周期的单位, 时钟周期也称为振荡周期,定义为时钟频率的倒数。时钟周期是计算机中最基本的、最小的时间单位。在一个时钟周期内,CPU仅完成一个最基本的动作

一个时钟周期是多少时间,取决于CPU的主频。如CPU主频为3.0GHZ,则一个时钟周期 = 1 / 3GHZ = 1 / 3*10^9HZ ≈ 0.33 * 10^-9 秒。 ( 1ns是一秒的十亿分之一,就是等于10的负9次方秒,即1 ns = 10^(-9)s )

好 以上是一些零碎知识小补充。

  • 一次主内存的访问通常在几十到几百个时钟周期
  • 一次L1高速缓存的读写只需要1~2个时钟周期
  • 一次L2高速缓存的读写也只需要数十个时钟周期

好 以上是从各种地方扒来的cpu和内存的工作效率补充。

cpu执行一个指令,可能仅仅需要几个时钟周期,但是和主内存的数据交互通信确需要几十上百个时钟周期,这样就会导致cpu一直在那傻等着内存处理完数据。

于是为了避免这个情况,神仙们设计了cpu缓存这种东西。

按照读取顺序与CPU结合的紧密程度,CPU缓存可分为:

  • 一级缓存:简称L1 Cache,位于CPU内核的旁边,是与CPU结合最为紧密的CPU缓存
  • 二级缓存:简称L2 Cache,分内部和外部两种芯片,内部芯片二级缓存运行速度与主频相同,外部芯片二级缓存运行速度则只有主频的一半
  • 三级缓存:简称L3 Cache,部分高端CPU才有

上面这也是我搬来的,因为我并不懂硬件。

然后cpu想去读取数据的时候,他会一级一级的按照缓存去查找,首先是一级,一级没有就去二级,二级没有就去三级,没有三级或者三级没有(这话真绕)就去内存中去找。每一级缓存的命中率大概有百分之八十吧,所以效率显著提升,因为这样就不用等上面说的几十上百时钟周期的内存数据通信了。

这时候再补充一点CPU缓存行的东西。

cpu缓存是分行的,一行对应一部分的存储空间,这b玩意儿就叫缓存行。有32 64 128的,一般来说就是64位的。

因为有局部性原理的存在(这个去百度吧),cpu会去一级一级往各级缓存去确认有没有存储某个地址的数据,就上面说的那百分之八十的玩意儿。此时通过MESI协议来区分各缓存行数据的四种状态,只有当数据处于s(share)的时候,其他cpu核心才能去读取这个状态。当cpu试图修改某个缓存行的时候,得向总线发出请求,把这个缓存行设置为E(Exclusive)独占状态才能进行修改。

这个地方还会涉及一个总线嗅探的内容。回头再琢磨。

我的思考

我们这个时候是不是就可以把volatile想成是用来保持cpu各核心之间缓存一致性的一个工具。

这个时候,是不是就觉得所谓JMM和CPU缓存这俩玩意儿是不是有很多地方很相似。

我是不是可以把JMM的工作内存当做cpu各级缓存和寄存器的一个抽象实现?

此时我的想法是,那多套这么一层的意义何在?

我个人的想法是,JAVA当年吹得牛逼是什么,write once ,run anywhere。

本质上JVM就像一个接口,然后各种os就是JVM这个接口的不同实现方法。

如果没有JMM这种抽象模型去控制,那么java就会丧失吹这种牛逼的资格。因为在不同的os下,cpu架构下,缓存一致性的保障方式是不相同的。

JMM就是缓存思想的一个体现。

那么volatile这玩意儿实现其功能的原理就是通过插入内存屏障。

然后内存屏障这玩意儿在硬件上的意义如下。

SFENCE:在该指令前的写操作必须在该指令后的写操作前完成

LFENCE:在该指令前的读操作必须在该指令后的读操作前完成

MFENCE:在该指令前的读写操作必须在该指令后的读写操作前完成

但是!java在JVM中实现的内存屏障不是通过cpu的fence指令。而是通过lock前缀指令来达成的。

lock前缀指令实现了类似内存屏障的功能,

  • 锁住对应的缓存行的数据,让其他cpu核心暂时没有办法访问该缓存行的内容。
  • lock前缀指令后的写操作会把缓存行中的数据刷新回主内存,并让其他核心的缓存行失效。
  • 实现防止前后指令的重排序。

所以我的理解中,jvm通过MESI的缓存一致性协议来实现了volatile的功能。

更正如下!

所以jvm使用lock前缀指令 利用了mesi协议 去实现了JMM层面的可见性重排序功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值