缓存一致性协议(MESI)
在目前主流的计算机中,cpu执行计算的主要流程如图所示:
数据加载的流程如下:
- 将程序和数据从硬盘加载到内存中
- 将程序和数据从内存加载到缓存中(目前多三级缓存,数据加载顺序:L3->L2->L1)
- CPU将缓存中的数据加载到寄存器中,并进行运算
- CPU会将数据刷新回缓存,并在一定的时间周期之后刷新回内存
缓存一致性协议发展背景
现在的CPU基本都是多核CPU,服务器更是提供了多CPU的支持,而每个核心也都有自己独立的缓存,当多个核心同时操作多个线程对同一个数据进行更新时,如果核心2在核心1还未将更新的数据刷回内存之前读取了数据,并进行操作,就会造成程序的执行结果造成随机性的影响,这对于我们来说是无法容忍的。
而总线加锁是对整个内存进行加锁,在一个核心对一个数据进行修改的过程中,其他的核心也无法修改内存中的其他数据,这样会导致CPU处理性能严重下降。
缓存一致性协议提供了一种高效的内存数据管理方案,它只会对单个缓存行(缓存行是缓存中数据存储的基本单元)的数据进行加锁,不会影响到内存中其他数据的读写。因此,我们引入了缓存一致性协议来对内存数据的读写进行管理。
MESI协议
缓存一致性协议有MSI,MESI,MOSI,Synapse,Firefly及DragonProtocol等等,接下来我们主要介绍MESI协议。
MESI分别代表缓存行数据所处的四种状态,通过对这四种状态的切换,来达到对缓存数据进行管理的目的。
状态 | 描述 | 监听任务 |
M 修改(Modify) | 该缓存行有效,数据被修改了,和内存中的数据不一致,数据只存在于本缓存行中 | 缓存行必须时刻监听所有试图读该缓存行相对应的内存的操作,其他缓存须在本缓存行写回内存并将状态置为E之后才能操作该缓存行对应的内存数据 |
E 独享、互斥(Exclusive) | 该缓存行有效,数据和内存中的数据一致,数据只存在于本缓存行中 | 缓存行必须监听其他缓存读主内存中该缓存行相对应的内存的操作,一旦有这种操作,该缓存行需要变成S状态 |
S 共享(Shared) | 该缓存行有效,数据和内存中的数据一致,数据同时存在于其他缓存中 | 缓存行必须监听其他处理器修改该缓存行相对应的本地缓存行的操作,一旦有这种操作,该缓存行需要变成I状态 |
I 无效(Invalid) | 该缓存行数据无效 | 无 |
备注:
1. MESI协议只对汇编指令中执行加锁操作的变量有效,表现到java中为使用volatile关键字定义变量或使用加锁操作
2. 对于汇编指令中执行加锁操作的变量,MESI协议在以下两种情况中也会失效:
a. CPU不支持缓存一致性协议。
b. 该变量超过一个缓存行的大小,缓存一致性协议是针对单个缓存行进行加锁,此时,缓存一致性协议无法再对该变量进行加锁,只能改用总线加锁的方式。
MESI工作原理
缓存一致性协议通过监控独立的loads和stores指令来监控缓存同步冲突,并确保不同的处理器对于共享内存的状态有一致性的看法。当一个处理器loads或stores一个内存地址a时,它会在bus总线上广播该请求,其他的处理器和主内存都会监听总线(也称为snooping)。此处统一默认CPU为单核CPU,在多核CPU内部执行过程和以下流程一致。
1、CPU1从内存中将变量a加载到缓存中,并将变量a的状态改为E(独享),并通过总线嗅探机制对内存中变量a的操作进行嗅探
2、此时,CPU2读取变量a,总线嗅探机制会将CPU1中的变量a的状态置为S(共享),并将变量a加载到CPU2的缓存中,状态为S
3、CPU1对变量a进行修改操作,此时CPU1中的变量a会被置为M(修改)状态,而CPU2中的变量a会被通知,改为I(无效)状态,此时CPU2中的变量a做的任何修改都不会被写回内存中(高并发情况下可能出现两个CPU同时修改变量a,并同时向总线发出将各自的缓存行更改为M状态的情况,此时总线会采用相应的裁决机制进行裁决,将其中一个置为M状态,另一个置为I状态,且I状态的缓存行修改无效)
4、CPU1将修改后的数据写回内存,并将变量a置为E(独占)状态
5、此时,CPU2通过总线嗅探机制得知变量a已被修改,会重新去内存中加载变量a,同时CPU1和CPU2中的变量a都改为S状态
在上述过程第3步中,CPU2的变量a被置为I(无效)状态后,只是保证变量a的修改不会被写回内存,但CPU2有可能会在CPU1将变量a置为E(独占)状态之前重新读取内存中的变量a,这个取决于汇编指令是否要求CPU2重新加载内存。
一个缓存一致性协议的完整描述可以很复杂,但是如下是我们比较感兴趣的主要状态转换:
- 当一个处理器请求使用exclusive模式加载load一个缓存行时,其他的处理器会将所有它们自己关于该缓存行的副本都置为invalid。任何一个已修改过自己本地的该对应缓存行的处理器都需要首先将其写回到内存中,之后第一个处理器的load请求才可以被满足。
- 当一个处理器请求使用shared模式加载load一个缓存行时,任何一个以exclusive模式加载该line的处理器都必须将其状态置为shared,并且任何一个已经修改过自己本地对应缓存行的处理器都必须将该line写回主内存,之后第一个处理器的load请求才可以被满足。
- 如果缓存满了,则可能需要驱逐一个缓存行。如果该line是shared或exclusive状态,那么它可以直接简单的被丢弃。但是如果该line被修改过,那么它必须被首先写回内存之后再丢弃。
总结
以上就是MESI的执行原理,MESI协议只能保证并发编程中的可见性,并未解决原子性和有序性的问题,所以只靠MESI协议是无法完全解决多线程中的所有问题。
原文地址:https://blog.csdn.net/alignjava/article/details/99070162
缓存一致性协议(MESI)相关推荐
- CPU缓存一致性协议MESI - 笔记
CPU缓存一致性协议MESI CPU高速缓存(Cache Memory) CPU为何要有高速缓存 CPU在摩尔定律的指导下以每18个月翻一番的速度在发展,然而内存和硬盘的发展速度远远不及CPU.这就造 ...
- 多核CPU缓存一致性协议MESI
在计算机系统中,CPU高速缓存(英语:CPU Cache)是用于减少处理器访问内存所需平均时间的部件.在金字塔式存储体系中它位于自顶向下的第二层,仅次于CPU寄存器.其容量远小于内存,但速度却可以接近 ...
- CPU 缓存一致性协议 MESI
CPU 高速缓存(Cache Memory) CPU 为何要有高速缓存 CPU 在摩尔定律的指导下以每 18 个月翻一番的速度在发展,然而内存和硬盘的发展速度远远不及 CPU.这就造成了高性能能的内存 ...
- 两个例子详解并发编程的可见性问题和有序性问题,通过volatile保证可见性和有序性以及volatile的底层原理——缓存一致性协议MESI和内存屏障禁止指令重排
1. 并发编程的可见性问题 2. 并发编程的有序性问题 3. 使用volatile关键字解决可见性问题 4. 可见性问题的本质--缓存不一致 因为cpu执行速度很快,但是内存执行速度相对于CPU很慢, ...
- 同时存多个变量缓存 微信小程序_CPU缓存一致性协议MESI,memory barrier和java volatile...
MESI协议 MESI协议是一个被广泛使用的CPU缓存一致性协议.我们都知道在CPU中存在着多级缓存,缓存级别越低,容量就越小,速度也越快.有了缓存,CPU就不需要每次都向主存读写数据,这提高了CPU ...
- CPU缓存一致性协议MESI
吹剑出自<庄子>:"夫吹管也,犹有也:吹剑首者,而已矣." 吹剑只能发出小声,以示自谦."并发吹剑录",表达的是笔者斗胆讲一些并发编程有关的知识,由 ...
- 缓存一致性协议-MESI
背景 带有高速缓存的CPU执行计算的流程 程序以及数据被加载到主内存 指令和数据被加载到CPU的高速缓存 CPU执行指令,把结果写到高速缓存 高速缓存中的数据写回主内存 高速缓存的数据结构 高速缓存的 ...
- 并发编程中的可见性——缓存一致性协议MESI
一.应用场景展示--多线程计数 1.全局原子操作计数的数据流图 核心问题就是不同CPU如何在同一时刻看到同样的全局变量值. 2.每线程自增计数的数据流图 二.cache原理和实现 1. cache g ...
- 缓存一致性协议(MESI)——缓存加锁协议
参考自: 缓存一致性协议(MESI) - 简书存储器层次结构中,最快速的就是cpu一级别 在目前主流的计算机中,cpu执行计算的主要流程如图所示: 数据加载的流程如下: 将程序和数据从硬盘加载到内存中 ...
- 深入学习缓存一致性问题和缓存一致性协议MESI(二)
写缓冲器与无效化 (想自学习编程的小伙伴请搜索圈T社区,更多行业相关资讯更有行业相关免费视频教程.完全免费哦!) 背景: MESI 协议解决了缓存一致性问题, 但是其自身也存在一个性能弱点--处理器执 ...
最新文章
- 一个对象的属性_【前端冷知识】如何判断一个对象的某个属性是可写的?
- [zz] C++智能指针循环引用解决
- html5获取域对象,entity-framework – EF5如何获取域对象的导航属性列表
- linux磁盘管理------LVM
- linux 改变文件夹属性,技术|在Linux中用chattr和lsattr命令管理文件和目录属性
- Win32汇编学习(7):鼠标输入消息
- python 快速排名发包_百度发包快排【SEO超快速排名系统】 - 「黑酷SEO」
- Java中.setvalue(-1)_Java Extension.setValue方法代码示例
- 宽带拨号找不到netcfg.hlp文件
- 2020年Java集合课堂笔记
- PowerPoint储存此文件时发生错误 出现错误的问题解决方法
- cmd窗口的内容加上颜色
- 如何取消OPPOA33Android系统,OPPO A33系统降级教程_OPPO A33怎么回退到原来旧版本的系统...
- 美通社企业新闻汇总 | 2019.1.23 | 上海迪士尼建疯狂动物城园区;戴森运营总部移至新加坡...
- python代理ip怎么写_python代理ip怎么写
- 软件设计-UML类图详解说明
- 和讯金融界证券之星 财经网站竞争格局突变
- Python二级(04)——Python语言基本语法元素
- 【Unity 骨骼动画】骨骼IK
- NPT 时间服务实战