缓存一致性协议-MESI是什么?

62eedf193dd0bd3a03074edafb5f6490.png

背景

上文:内存屏障是什么? 本文是继上文的解决内存不一致的另一种实现方式。根据上文我们了解到cpu加载执行计算的流程:

1、程序和数据被加载到主内存中(Main Memory)

2、指令和数据被加载到CPU的高速缓存(L1、L2、L3)

3、CPU执行完指令,结果同步到高速缓存(L1、L2、L3)

4、最后将高速缓存中的数据同步到主内存中(Main Memory)

所以在多CPU的情况下加载回主内存或缓存需要保持缓存一致性要么加锁,要么用于本文的MESI来实现。

缓存一致性协议-MESI是什么?

MESI是Modify(修改)、Exclusive(独享、互斥)、Shared(共享)、Invalid(无效)首字母组成的。用于对单个缓存行的数据进行加锁,不会影响到内存中其他数据的读写。

状态

描述

监听任务

M 修改 (Modified)

该Cache line有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中。

缓存行必须时刻监听所有试图读该缓存行相对就主存的操作,这种操作必须在缓存将该缓存行写回主存并将状态变成S(共享)状态之前被延迟执行。

E 独享、互斥 (Exclusive)

该Cache line有效,数据和内存中的数据一致,数据只存在于本Cache中。

缓存行也必须监听其它缓存读主存中该缓存行的操作,一旦有这种操作,该缓存行需要变成S(共享)状态。

S 共享 (Shared)

该Cache line有效,数据和内存中的数据一致,数据存在于很多Cache中。

缓存行也必须监听其它缓存使该缓存行无效或者独享该缓存行的请求,并将该缓存行变成无效(Invalid)。

I 无效 (Invalid)

该Cache line无效。

缓存行是什么?d2f635b9d59f1e4f709af08ab5704f3c.png

缓存行(cache line)是缓存存储数据的单位,也是cpu缓存的最小单位。一般大小为64Byte。所以上面的四种状态就是保存在缓存行中,每个状态需要2个Bit位去存储(就是Flag)。、

什么是缓存行伪共享?

当多个cpu在多线程修改互相独立的变量时,如果其中某些变量共享同一个缓存行,就会无意中影响彼此的性能,这种称为伪共享。

个人理解:就像你用有道笔记一样,在苹果电话和windows有同一个文件,当一方修改会同步给另一方,导致另一方被更新了。这种有点类似内存的可见性,比如某些变量用volotail。

如何避免伪共享?

方法1:利用jdk8的注解:@sun.misc.Contended ,通过添加该注解会自动补齐缓存行。

@sun.misc.Contended
public final static class TestlONG {
    public volatile long test = 0L;
  
}

注意该注解需要开启jvm配置:

-XX:-RestrictContended

方法2 :在两个long类型的变量之间再加7个Long类型。(一个缓存行是64个字段,一个Long类型是8字节)

class Test {
    volatile long a;
    long p1, p2, p3, p4, p5, p6, p7;
    volatile long b;
}

MESI状态有哪些?

ba24f1237d2322af78b689536cb03ba8.png

以上是触发的MESI状态图,分别为本地读取、本地写入、远端读取、远端写入,如下表描述。

触发事件

描述

本地读取(Local read)

本地cache读取本地cache数据

本地写入(Local write)

本地cache写入本地cache数据

远端读取(Remote read)

其他cpu内核读取了DRAM中当前内核的缓存行

远端写入(Remote write)

其他cpu内核写入了DRAM中当前内核的缓存行

不同场景的触发如下

假设我们有两个核core0和core1当发生不同状态修改的时候会发生不同的事件。

状态是M(修改)

事件

行为

下一个状态

local read

直接从core0的cache中读,状态不发生改变

M

local write

直接修改core0的cache数据,状态不变

M

remote read

core1需要最新数据,将core0的内容写回到RAM中
core1从RAM再读取值,core0和core1的缓存行标志为设置为S

S

remote write

先将core0的值写回到RAM中
core1读取值并修改,core0的状态变为I,core1的状态变为M

I

状态是S(共享)

事件

行为

下一个状态

local read

直接从core0的cache中读,状态不发生改变

S

local write

core0直接修改cache,状态变为M。core1变为I(失效)

M

remote read

core1读的和core0的一样的数据,状态不变

S

remote write

core1对应成了上面core0的local write,core1的cache变为M,core0的变为I(失效)

I

状态是E(独占)

事件

行为

下一个状态

local read

直接从core0的cache中读,状态不发生改变

E

local write

直接修改core0的cache,状态变为M

M

remote read

core1发送读事件,core0和core1需要共享内容,所以状态都变为S

S

remote write

core0将内容置为I(失效)

I

状态是I(失效)

事件

行为

下一个状态

local read

如果core1没有内容,则core0读取内容,状态为E
如果core1有内容,状态为M,则core1需要写回到RAM,然后core0读取,状态变为S
如果core1有内容,状态为S或者E,那么core0直接读,core0和core1都变为S

E or S

local write

core0需要从RAM拉取数据
如果core1没有内容,那么core0就直接拉取,修改后设置为M
如果core1有内容,状态为M,那么core1需要先写回RAM,然后core0读取最新到cache,修改并设置为M,core1变为I
如果core1有内容,状态为S或者E,那么core0读取并设置为M,core1为I(失效)

M

remote read

已经失效,只和自己读写有关,和其他的读写无关,状态不变。

I

remote write

已经失效,只和自己读写有关,和其他的读写无关,状态不变。

I

最终汇致如下图

a1fedeebd4e00947604495f877a8810c.png

最后

关于MESI的确是一种解决内存屏障一种方式,并且被各大语言规范引用了,当然该内容还是比较底层涉及硬件知识及相关的硬件处理配置,所以可能看起来比较深奥,建议新手同学可以看看下面的参考资料,深入学习了解。

参考资料:

https://baike.baidu.com/item/MESI%E5%8D%8F%E8%AE%AE/22742331

https://note.youdao.com/ynoteshare/index.html?id=73fc01483ff8b40c47d6898ad17a66c8&type=note&_time=1668342395100?auto

https://juejin.cn/post/7065616174712619015

https://www.cnblogs.com/yanlong300/p/8986041.html

https://www.cnblogs.com/cyfonly/p/5800758.html 写得好~

https://juejin.cn/post/7001122798122827806

https://www.zhihu.com/question/296949412#!

https://zhuanlan.zhihu.com/p/351550104

https://www.cnblogs.com/gunduzi/p/13590528.html

视频资料:

https://www.bilibili.com/video/BV1fK4y1E7NC/?vd_source=7d0e42b081e08cb3cefaea55cc1fa8b7

https://www.bilibili.com/video/BV1pC4y1W7zS/?vd_source=7d0e42b081e08cb3cefaea55cc1fa8b7

<think>好的,我现在需要帮助用户理解MESI协议的工作原理和实现细节。用户已经提供了一些参考资料,我需要结合这些信息来组织一个清晰的中文回答,并生成相关问题。首先,我得确保自己正确理解MESI协议的基本概念和各个状态的含义。 首先,MESI代表缓存行的四种状态:Modified(已修改)、Exclusive(独占)、Shared(共享)和Invalid(无效)。这四种状态用于协调多核CPU之间的缓存一致性。我需要解释每个状态的含义以及它们之间的转换过程。 接下来,我需要考虑用户提供的引用内容。引用1提到MESI缓存一致性协议,协调多核CPU缓存数据一致。引用2说明MESI是基于写-失效的协议,支持回写缓存,允许缓存缓存的复制,减少主存事务。引用3则指出当变量超过缓存行大小时,MESI无法加锁,需改用总线加锁。这些点都要整合到回答中。 然后,我需要按照用户的要求,使用行内数学表达式用$...$,独立公式用$$...$$。不过目前内容可能不需要数学公式,但需要检查是否有需要的地方,比如状态转换的条件。如果有,可能需要用行内公式表示某些条件或变量。 回答结构需要清晰,分步骤或分点解释。例如,先介绍四种状态,再讲工作原理,包括读操作和写操作的处理,总线嗅探机制,以及状态转换的条件。同时,要注意实现细节,如总线加锁的情况。 在生成相关问题部分,需要提出与MESI协议相关的问题,可能涉及与其他协议比较、性能优化、实际应用中的挑战等。例如,MESI与其他协议的区别,多核系统中的挑战,如何优化性能,以及状态转换的具体情况。 最后,检查是否符合所有用户的要求:正确使用LaTeX格式(虽然可能这里用不上),中文回答,生成相关问题,引用标识正确添加,结构清晰。还要确保没有使用Markdown格式,段落之间用空行分隔,代码块用三个反引号包裹。 现在开始组织内容: 1. MESI协议概述:定义和作用,确保多核缓存一致性。 2. 四种状态:分别解释每个状态,用列表形式。 3. 工作原理:读操作和写操作的处理流程,状态转换。 4. 总线嗅探机制:如何监听总线,更新状态。 5. 实现细节:如缓存行大小限制,总线加锁的情况。 6. 引用对应的引用内容,在适当的位置添加引用标识。 需要确保每个引用出现在正确的地方,比如引用3关于缓存行大小的问题放在实现细节部分。引用2关于回写缓存和性能优化的部分可以放在工作原理或状态转换部分。 可能遇到的问题:如何简洁地解释状态转换,避免过于技术化。需要用简单的中文术语,让用户容易理解。 现在开始撰写回答,确保结构清晰,分点说明,并自然地融入引用。最后生成相关问题。</think>MESI协议是维护多核CPU缓存一致性的核心机制,通过四种状态标记和总线嗅探机制实现高效数据同步。其工作原理可分为以下关键点: ### 一、MESI状态定义 每个缓存行通过4种状态协调数据访问: 1. **Modified (已修改)** 数据仅存于当前缓存,与主内存不一致,具有修改权限 2. **Exclusive (独占)** 数据仅存于当前缓存,与主内存一致,具备修改权限 3. **Shared (共享)** 数据存在于多个缓存,所有副本与主内存一致 4. **Invalid (无效)** 缓存行数据不可用,需重新获取[^1] ### 二、核心工作原理 #### 1. 读操作处理 - 若本地缓存为Modified状态:直接读取数据 - 若本地缓存为Invalid状态:发起总线请求 - 其他缓存有Modified数据:先将数据写回主存,再传输给请求方,双方转为Shared状态 - 其他缓存无有效数据:从主存加载,转为Exclusive状态[^2] #### 2. 写操作处理 - 当前状态为Modified/Exclusive:直接修改 - 当前状态为Shared:向总线发送Invalidate信号,其他缓存副本失效后转为Modified状态 - 当前状态为Invalid:触发Read-Invalidate事务,获取数据所有权后修改 #### 3. 总线嗅探机制 所有缓存控制器持续监听总线,检测到相关操作时自动更新状态。例如监听到Invalidate信号时,将对应缓存行标记为Invalid[^3] ### 三、关键实现特性 1. **缓存行粒度控制** 协议以缓存行为单位管理状态,当变量跨越多缓存行时,需改用总线锁保证原子性 2. **状态转换优化** 通过E状态避免无竞争时的总线事务,减少约50%的读操作带宽消耗 3. **写传播策略** 采用回写模式,仅当缓存行被替换或收到请求时才写回主存,降低总线压力 ```c // 典型状态转换伪代码示例 void handle_write_request(CacheLine* line) { if (line->state == SHARED) { broadcast_invalidate_signal(); line->state = MODIFIED; } else if (line->state == INVALID) { fetch_data_from_memory(); line->state = MODIFIED; } // 执行数据写入 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值