MESI 协议

MESI 协议背景现代处理器为了提高访问数据的效率 在每个 CPU 核心上都会有多级容量小 速度快的缓存 L1cache L2cache 多核心共享 L3cache 等 用于缓存常用的数据 由于从内存取数据要比从缓存取数据慢近 100 倍 数据被修改时也只是先更新 cache 并不是直接写回到主存中 由此造成了缓存中的数据与内存不一致 如果系统是单核处理器 所有线程看到的都是缓存中的最新数据 当然没有问题 但如果系统是多核处理器 同一份主存数据可能会被缓存到多个核心 cache 中 在运行中只要其中一个核心修改了缓存中的值 如

背景

现代处理器为了提高访问数据的效率,在每个CPU核心上都会有多级容量小,速度快的缓存(L1 cache,L2 cache,多核心共享L3 cache等),用于缓存常用的数据。由于从内存取数据要比从缓存取数据慢近100倍,数据被修改时也只是先更新cache,并不是直接写回到主存中。由此造成了缓存中的数据与内存不一致。如果系统是单核处理器,所有线程看到的都是缓存中的最新数据,当然没有问题。但如果系统是多核处理器,同一份主存数据可能会被缓存到多个核心 cache中,在运行中只要其中一个核心修改了缓存中的值,如果其他CPU核心没有得到及时的通知,就会造成缓存不一致的情况,影响系统的运行结果。MESI协议的出现,就是为了解决多核处理器时代,缓存不一致的问题的。(Intel 是MESI,其他厂商还有MOSI、MSI、Dragon Firefly等)

概念

MESI协议
NUMA架构CPU
由图可知,每个Socket代表一个CPU插槽,一个CPU包含多个核心core,每个核心有自己私有的L1,L2级缓存,同时每个核心共享L3级缓存,多个CPU共享主存。其中,缓存中的最小缓存单元称之为缓存行(cache-line),在X86架构下,cache-line长度为64字节。MESI就代表者cache-line的四种缓存状态。MESI协议基于内存屏障、锁总线(无法锁缓存行时)机制实现。

当CPU要读取数据时,只要缓存的状态不是I都可以从缓存中读,否则就要从主存中读取。这一读操作可能会被某个处于M或E状态的CPU截获,该CPU将修改的数据写出到内存,并将自己设为S状态后这一读操作才继续进行。只有缓存状态是E或M时,CPU才可以修改其中的数据,修改后缓存即处于M状态。如果CPU要修改数据时发现其缓存不处于E或M状态,则需要发出特殊的RFO指令(Read For Ownership),将其它CPU的缓存设为I状态。

MESI状态转换图
在这里插入图片描述

转换过程说明:

第一:某个CPU(CPU A)发起本地写请求(Local Write),比如对某个内存地址的变量赋值,如果此时如果所有CPU的Cache中都没加载此内存地址,即此内存地址对应的Cache Line为无效状态(Invalid),则CPU A中的Cache Line保存了最新内存变量值以后,其状态被修改为Modified。随后,如果CPU B发起对同一个变量的读操作(Remote Read),则CPU A在总线上嗅探到这个读请求以后,先将Cache Line里修改过的数据回写(Write Back)到Memory中,然后在内存总线上放一份Cache Line的拷贝作为应答,最后再将自身的Cache Line的状态修改为Shared,由此产生的结果是CPU A与CPU B里对应的Cache Line的状态都为Shared。

第二:在第一点的基础上,CPU A发起本地写请求导致自身的Cache Line状态变为Modified以后,如果此时CPU B发起同一个内存地址的写请求(Remote Write),则我们看到状态图里此时CPU A的Cache Line状态为Invalid,其原因是如下:CPU B此时发出的是一个特殊的请求——“读并且打算修改数据”(read with intent to modify),当CPU A从总线上嗅探到这个请求后,会先阻止此请求并取得总线的控制权(Takes control of bus),随后将Cache Line里修改过的数据回写(Write Back)到Memory中,再将此Cache Line的状态修改为Invalid(这是因为其他CPU要改数据,所以没必要改为Shared了)。与此同时,CPU B发现之前的请求并没有得到响应,于是重新再发起一次请求,此时由于所有CPU的Cache里都没有内存副本了,所以CPU B的Cache就从Memory中加载最新的数据到Cache Line中,随后修改数据,然后改变Cache Line的状态为Modified。

缓存行伪共享问题

总结

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/225046.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 上午10:15
下一篇 2026年3月17日 上午10:15


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号