MESI缓存一致性协议

MESI协议 

     缓存一致性协议有MSI,MESI,MOSI,Synapse,Firefly及DragonProtocol等等,接下来我们主要介绍MESI协议。MESI分别代表缓存行数据所处的四种状态,通过对这四种状态的切换,来达到对缓存数据进行管理的目的

状态 描述 监听任务
M 修改(Modify) 该缓存行有效,数据被修改了,和内存中的数据不一致,数据只存在于本缓存行中 缓存行必须时刻监听所有试图读该缓存行相对应的内存的操作,其他缓存须在本缓存行写回内存并将状态置为E之后才能操作该缓存行对应的内存数据
E 独享、互斥(Exclusive) 该缓存行有效,数据和内存中的数据一致,数据只存在于本缓存行中 缓存行必须监听其他缓存读主内存中该缓存行相对应的内存的操作,一旦有这种操作,该缓存行需要变成S状态
S 共享(Shared) 该缓存行有效,数据和内存中的数据一致,数据同时存在于其他缓存中 缓存行必须监听其他处理器修改该缓存行相对应的本地缓存行的操作,一旦有这种操作,该缓存行需要变成I状态
I 无效(Invalid) 该缓存行数据无效

MESI缓存一致性协议_第1张图片

数据加载的流程如下:

  1. 将程序和数据从硬盘加载到内存中
  2. 将程序和数据从内存加载到缓存中(目前多三级缓存,数据加载顺序:L3->L2->L1)
  3. CPU将缓存中的数据加载到寄存器中,并进行运算
  4. CPU会将数据刷新回缓存,并在一定的时间周期之后刷新回内存

1.MESI协议只对汇编指令中执行加锁操作的变量有效,表现到java中为使用volatile关键字定义变量或使用加锁操作

2. 对于汇编指令中执行加锁操作的变量,MESI协议在以下两种情况中也会失效:

a. CPU不支持缓存一致性协议。

b. 该变量超过一个缓存行的大小,缓存一致性协议是针对单个缓存行进行加锁,此时,缓存一致性协议无法再对该变量进行加锁,只能改用总线加锁的方式。

MESI缓存一致性协议_第2张图片

工作内存与主内存交互

物理机高速缓存和主内存之间的交互有协议,同样的,java内存中线程的工作内存和主内存的交互是由java虚拟机定义了如下的8种操作来完成的,每种操作必须是原子性的(double和long类型在某些平台有例外,参考volatile详解和非原子性协定) java虚拟机中主内存和工作内存交互,就是一个变量如何从主内存传输到工作内存中,如何把修改后的变量从工作内存同步回主内存。

  • lock(锁定):作用于主内存的变量,一个变量在同一时间只能一个线程锁定,该操作表示这条线成独占这个变量
  • unlock(解锁):作用于主内存的变量,表示这个变量的状态由处于锁定状态被释放,这样其他线程才能对该变量进行锁定
  • read(读取):作用于主内存变量,表示把一个主内存变量的值传输到线程的工作内存,以便随后的load操作使用
  • load(载入):作用于线程的工作内存的变量,表示把read操作从主内存中读取的变量的值放到工作内存的变量副本中(副本是相对于主内存的变量而言的)
  • use(使用):作用于线程的工作内存中的变量,表示把工作内存中的一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时就会执行该操作
  • assign(赋值):作用于线程的工作内存的变量,表示把执行引擎返回的结果赋值给工作内存中的变量,每当虚拟机遇到一个给变量赋值的字节码指令时就会执行该操作
  • store(存储):作用于线程的工作内存中的变量,把工作内存中的一个变量的值传递给主内存,以便随后的write操作使用
  • write(写入):作用于主内存的变量,把store操作从工作内存中得到的变量的值放入主内存的变量中

总结

以上就是MESI的执行原理,MESI协议只能保证并发编程中的可见性,并未解决原子性和有序性的问题,所以只靠MESI协议是无法完全解决多线程中的所有问题。

参考链接:

https://blog.csdn.net/weixin_39597987/article/details/110792959

https://blog.csdn.net/m0_37962779/article/details/113843743

你可能感兴趣的:(Java,汇编,java,多线程,并发编程)