缓存一致性协议(MESI协议)

大家都知道,计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题,由于CPU执行速度很快,而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多,因此如果任何时候对数据的操作都要通过和内存的交互来进行,会大大降低指令执行的速度。因此在CPU里面就有了高速缓存(Cache).

也就是,当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中。举个简单的例子,比如下面的这段代码:

i = i+1;

当线程执行这个语句时,会先从主存当中读取i的值,然后复制一份到高速缓存当中,然后CPU执行指令对i进行加1操作,然后将数据写入高速缓存,最后将高速缓存中i最新的值刷新到主存当中。

这个代码在单线程中运行是没有任何问题的,但是在多线程中运行就会有问题了。在多核CPU中,每条线程可能运行于不同的CPU中,因此每个线程运行时有自己的高速缓存(对单核CPU来说,其实也会出现这种问题,只不过是以线程调度的形式来分别执行的)。本文我们以多核CPU为例。

比如同时有2个线程执行这段代码,假如初始时i的值为0,那么我们希望两个线程执行完之后i的值变为2。但是事实会是这样吗?

  可能存在下面一种情况:初始时,两个线程分别读取i的值存入各自所在的CPU的高速缓存当中,然后线程1进行加1操作,然后把i的最新值1写入到内存(主存)。此时线程2的高速缓存当中i的值还是0,进行加1操作之后,i的值为1,然后线程2把i的值写入内存(主存)。

  最终结果i的值是1,而不是2。这就是著名的缓存一致性问题。通常称这种被多个线程访问的变量为共享变量。 
   
也就是说,如果一个变量在多个CPU中都存在缓存(一般在多线程编程时才会出现),那么就可能存在缓存不一致的问题。

  为了解决缓存不一致性问题,通常来说有以下2种解决方法:

  1)通过在总线加LOCK#锁的方式

  2)通过缓存一致性协议

  这2种方式都是硬件层面上提供的方式。

在早期的CPU当中,是通过在总线上加LOCK#锁的形式来解决缓存不一致的问题。因为CPU和其他部件进行通信都是通过总线来进行的,如果对总线加LOCK#锁的话,也就是说阻塞了其他CPU对其他部件访问(如内存),从而使得只能有一个CPU能使用这个变量的内存。比如上面例子中 如果一个线程在执行 i = i +1,如果在执行这段代码的过程中,在总线上发出了LCOK#锁的信号,那么只有等待这段代码完全执行完毕之后,其他CPU才能从变量i所在的内存读取变量,然后进行相应的操作。这样就解决了缓存不一致的问题。

  但是上面的方式会有一个问题,由于在锁住总线期间,其他CPU无法访问内存,导致效率低下。效率,我要的是效率!!!

  所以就出现了缓存一致性协议。最出名的就是Intel 的MESI协议,MESI协议保证了每个缓存中使用的共享变量的副本是一致的。它核心的思想是:当CPU写数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。

(0)

相关推荐

  • 到底什么是内存可见性?

    我们都知道,volatile保证了内存可见性和禁止指令重排,但是对于内存可见性这一条,我一直没有完全弄明白,今天咱们一起看一下,这个可见性,到底是如何可见,数据到底是如何可见的. 首先我们要达成一个共 ...

  • 用动图的方式,理解 CPU 缓存一致性协议!

    大家好,我是小林. 我之前写过 CPU 缓存一致性 MESI 协议:10 张图打开 CPU 缓存一致性的大门. 然后期间挺多人对 MESI 协议的转换有疑问,其实我在文章中把 MESI 协议状态切换的 ...

  • 大郎!快起来看多线程啦!贰

    一杯茶一包烟,一个Bug改一天!!相信很多"爱码仕"都曾经对着电脑几个小时就为改一个bug,最后是在美团小哥指点下修复的.他曾经也是王者,不为别的,就是喜欢送外卖锻炼身体还能远离产 ...

  • 小议CPU缓存一致性协议MESI

    你有没有听过缓存一致性协议?你是否了解CPU中的高速缓存?本文带你揭秘,从CPU的视角来看待并发编程. CPU架构 缓存与主存 解读缓存一致性(Cache Coherency),先看一下CPU的架构 ...

  • 10 张图打开 CPU 缓存一致性的大门

    来自公众号:小林coding 前言 直接上,不多 BB 了. 正文 CPU Cache 的数据写入 随着时间的推移,CPU 和内存的访问性能相差越来越大,于是就在 CPU 内部嵌入了 CPU Cach ...

  • 看懂这篇,才能说了解并发底层技术

    零.开局 前两天我搞了两个每日一个知识点,对多线程并发的部分知识做了下概括性的总结.但通过小伙伴的反馈是,那玩意写的比较抽象,看的云里雾里晕晕乎乎的. 所以又针对多线程底层这一块再重新做下系统性的讲解 ...

  • 内存模型和原子操作笔记

    内存模型和原子操作笔记

  • 分布式并发编程,线程安全性,原理分析

    初步认识 Volatile 一段代码引发的思考 下面这段代码,演示了一个使用 volatile 以及没使用volatile这个关键字,对于变量更新的影响 public class VolatileDe ...

  • 部标JT808协议JT809协议JT1078协议

    JT808是定位协议.通讯协议.基础协议:其他协议基于该协议进行扩展. JT809是转发协议.监管协议:第三方平台通过809向808进行数据获取与事件下发. JT1078是多媒体监控协议:视频.音频. ...

  • 七层协议 五层协议 四层协议关系

    表白:黑白圣堂血天使,天剑鬼刀阿修罗.  讲解对象:/七层协议 五层协议 四层协议关系 作者:融水公子 rsgz 网络安全 网络安全教程 http://www.rsgz.top/post/771.ht ...

  • 中标后订立背离合同实质性内容的协议,协议效力如何认定?

    柳跃亮 了不起的法律人 3天前 导 读 日常中,经常会有招标人与中标人不按照招标文件和中标人的投标文件订立合同,或者在订立中标合同后又签了背离合同实质性内容的其他协议,那么这类背离合同实质性内容的协议 ...

  • 精通企业网络当中网红协议OSPF协议

    OSPF协议 OSPF协议的工作机制类似于咱们的中国地图一样,咱们认拿着地图到达目标地点 ,路由器运行OSPF后,也会有一张类似于地图的东西,叫做LSDB(链路状态数据库)那么,路由器会利用这个LSD ...

  • 做充电器的看过来,这家协议芯片协议全外围简,月销量达千万颗

    协议芯片在充电器中,决定着充电器能支持什么设备,支持的协议多,也就说明充电器支持的设备多,能为更多设备进行快充.举个例子,苹果的96W充电器,只支持PD协议,对一些可以PPS快充的手机,只能进行PD充 ...

  • 面试官:缓存一致性问题怎么解决?

    关于Redis的其他的一些面试问题已经写过了,比如常见的缓存穿透.雪崩.击穿.热点的问题,但是还有一个比较麻烦的问题就是如何保证缓存一致性. 对于缓存和数据库的操作,主要有以下两种方式. 先删缓存,再 ...

  • 欧盟“脱欧”谈判代表巴尼耶警告:英欧双方或不能达成协议|达成协议|脱欧|欧盟

    原标题:欧盟"脱欧"谈判代表巴尼耶警告:英欧双方或不能达成协议 根据英国<金融时报>报道,欧盟"脱欧"谈判首席代表米歇尔·巴尼耶当地时间12月2日发 ...