Juc13_JVM-JMM-CPU底层执行全过程缓存一致性协议MESI

Posted TZ845195485

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Juc13_JVM-JMM-CPU底层执行全过程缓存一致性协议MESI相关的知识,希望对你有一定的参考价值。

下面的(1)(2)是我自己的理解,可能有误差,期待一个大佬指点下
简单来说是volatile激发了MESI
(1). volatile保证可见性,在汇编会有一个lock锁前缀,触发缓存一致性协议,保证了可见性
(2). volatile保证有序性,是基于它底层的内存屏障,loadload、StoreLoad、LoadStore、StoreStore

①. JVM-JMM-CPU底层执行全过程

  • ①. JVM(内存中)是基于栈的指令集架构,比如我们去执行一个运算的操作,最终是由CPU执行的

  • ②. 比如sconst_0这个指令会交给执行引擎进行翻译,解释执行器或JLT转换为汇编

  • ③. 汇编指令会转化为二进制

  • ④. 在二进制下面是线程A,需要这个线程作为载体

  • ⑤. cpu不是马上执行,而是CPU调度到线程A才执行线程A的代码

  • ⑥. KLT模式,JVM创建一个线程,底层会维护一个线程表,而这个线程与JVM中的线程是一一对应的关系
    在这里插入图片描述

②. 缓存一致性协议

  • ①. 变量加了volatile关键字,在汇编会有一个lock锁前缀(触发硬件缓存锁机制)
    硬件缓存锁机制包含总线锁、缓存一致性协

  • ②. 早期技术落后,使用总线保持缓存一致
    例子: 早期可能CPU还没有三级缓存,t1、t2两个线程(多核)对主内存中的数据进行修改,如果某一个时刻,t1线程拿到了CPU执行权,在写回到主内存去的时候,会将总线锁抢占,抢占后t2线程就没办法去进行写入的操作,早期的这种使用总线锁的效率很低,它只能保证一个线程去写,这样多核的也就没办法发挥写操作

  • ③. 缓存一致性协议(最经典的是MESI协议)
    (memi 在硬件约定了这样一种机制,CPU启动后,会采用一种监听模式,一直去监听总线里面消息的传递,也就是说,有任何人通过总线从内存中拿了一点东西,只要你被lock前缀修饰了,都可以感知到)

  1. 例如我们对主内存的数据x=0,t1线程进行赋值x=3,t2线程进行赋值x=5的操作
  2. 首先t1线程将x=0从内存–总线–读到三级缓存中,放入缓存行中存储,这时状态是E(独享的)
  3. t2线程也将x=0从内存–总线–读到三级缓存中,放入缓存行中存储,这时的状态是S(共享的),而t1线程读取到的也从E–S
  4. 这个时候t1将数据从3级缓存读到L2—L1中,t2线程也是如此
  5. 如果这个时候(情况一),这个时候t1上锁的话,那么会将t1的L1的缓存行锁住,然后将x=3(E-S-M),在写的同时,发出一个通知去告诉t2线程,这个时候t2线程就会将变量置为无效(S-I),也发出一个通知去通知线程t1的cpu,告诉它我这里置为无效了,读取到t1线程的x=3。至于什么时候t1线程将值写入主内存的时机是不确定的
  6. 如果这个时候(情况二),线程t1和线程t2同时都锁住了各自L3中的缓存行,这个时候,我们到底是执行谁的结果呢?这个时候由总线裁决,看执行谁的操作,是x=3还是x=5
    总线裁决:通过总线上面电路的高低电位,每一个cpu都有自己的时钟周期
  7. 情况三:如果变量很大,我们一个缓存行存不进去,这个时候MESI就会失效,会降级到总线的机制

在这里插入图片描述

以上是关于Juc13_JVM-JMM-CPU底层执行全过程缓存一致性协议MESI的主要内容,如果未能解决你的问题,请参考以下文章

juc学习二(CAS底层原理)

8_JUC三大辅助类

Juc14_CAS的概述Unsafe类的原理CAS缺点ABA问题如何解决

浅谈JUC工具CountDownLatch

Juc21_强大的三个工具类CountDownLatch 闭锁 CyclicBarrier Semaphore

Juc19_从字节码角度看synchronizeMonitor类monitorentermonitorexit