当前位置:首页 > 单片机 > 小林coding
[导读]大家好,我是小林。我之前写过CPU缓存一致性MESI协议:10张图打开CPU缓存一致性的大门。然后期间挺多人对MESI协议的转换有疑问,其实我在文章中把MESI协议状态切换的各个过程都总结成了一个表格,可能内容太多,很多小伙伴没有仔细看。就在昨天,我发现个可以「在线体验 MESI 协议状态转换」过程的网站,地址如下:https://www.scss.tcd.ie/Jeremy.Jones/VivioJS/caches/MESIHelp.htm我先给大家复习下MESI协议,然后再跟大家讲一些这个网站怎么用。MESI协议MESI协议其实是4个状态单词的开头字母缩写,分别是:Modified,已修改...

大家好,我是小林。我之前写过 CPU 缓存一致性 MESI 协议:10 张图打开 CPU 缓存一致性的大门。
然后期间挺多人对 MESI 协议的转换有疑问,其实我在文章中把 MESI 协议状态切换的各个过程都总结成了一个表格,可能内容太多,很多小伙伴没有仔细看。就在昨天,我发现个可以「在线体验 MESI 协议状态转换」过程的网站,地址如下:https://www.scss.tcd.ie/Jeremy.Jones/VivioJS/caches/MESIHelp.htm
我先给大家复习下 MESI 协议,然后再跟大家讲一些这个网站怎么用。

MESI 协议

MESI 协议其实是 4 个状态单词的开头字母缩写,分别是:
  • Modified,已修改

  • Exclusive,独占

  • Shared,共享

  • Invalidated,已失效

这四个状态来标记 Cache Line 四个不同的状态。「已修改」状态就是我们前面提到的脏标记,代表该 Cache Block 上的数据已经被更新过,但是还没有写到内存里。而「已失效」状态,表示的是这个 Cache Block 里的数据已经失效了,不可以读取该状态的数据。「独占」和「共享」状态都代表 Cache Block 里的数据是干净的,也就是说,这个时候 Cache Block 里的数据和内存里面的数据是一致性的。「独占」和「共享」的差别在于,独占状态的时候,数据只存储在一个 CPU 核心的 Cache 里,而其他 CPU 核心的 Cache 没有该数据。这个时候,如果要向独占的 Cache 写数据,就可以直接自由地写入,而不需要通知其他 CPU 核心,因为只有你这有这个数据,就不存在缓存一致性的问题了,于是就可以随便操作该数据。另外,在「独占」状态下的数据,如果有其他核心从内存读取了相同的数据到各自的 Cache ,那么这个时候,独占状态下的数据就会变成共享状态。那么,「共享」状态代表着相同的数据在多个 CPU 核心的 Cache 里都有,所以当我们要更新 Cache 里面的数据的时候,不能直接修改,而是要先向所有的其他 CPU 核心广播一个请求,要求先把其他核心的 Cache 中对应的 Cache Line 标记为「无效」状态,然后再更新当前 Cache 里面的数据。事实上,整个 MESI 的状态可以用一个有限状态机来表示它的状态流转。还有一点,对于不同状态触发的事件操作,可能是来自本地 CPU 核心发出的广播事件,也可以是来自其他 CPU 核心通过总线发出的广播事件。下图即是 MESI 协议的状态图:
MESI 协议的四种状态之间的流转过程,我汇总成了下面的表格,你可以更详细的看到每个状态转换的原因:

网站体验

接下来说说,怎么玩这个网站。
看上图,共分为三个部分:
  • 第一部分,内存。显示内存地址和数据;

  • 第二部分,CPU 缓存。显示 CPU 缓存的变量数据和 MESI 协议状态,因为我现在还没开始操作,所以显示的是空白。

  • 第三部分,CPU 操作。共有三个 CPU,每个 CPU 都有各自的 Cache,CPU 操作分别「读」和「写」,这部分是我们手动操作的部分。

而且 CPU 和内存之间有三条总线,分别是:
  • 数据总线(Data Bus):在CPU与内存之间来回传送需要处理或是需要储存的数据。

  • 地址总线(Adress Bus),用来指定在内存之中储存的数据的地址。

  • shared,这个我也不知道是什么总线,网上没搜到资料,网站上最细那条总线就是这个名字,作用是控制 Cache 的数据状态。

接下来,来演示下效果。我操作 CPU1 读取 a0 变量,此时页面会显示如下(实际上是有动画的效果的,我这里就不录制动图了,建议大家自己去操作一遍,自己感受下过程): 可以看到,CPU1 核心从内存读取了 a0 变量的数据,并缓存在了 Cache1 里,而且此时状态为 E (独占)。然后我操作 CPU2 读取 a0 变量,此时页面会显示如下:
可以看到,CPU1 和 CPU1 的 Cache 数据的状态都是 S(共享),和表格中表述的现象一致。别看我的结果是静态的,实际上当我操作完  CPU2 读取 a0 变量后,实际上是有动画效果的,这里有个小技巧,在动画的过程中,我们可以点击网站任意一个位置,就会暂停,然后再点击就开始,这样我们可以很清晰的知道这个状态过程是怎么通过这三个总线完成的。
我大概简述下过程:
  1. 点击 CPU2 的 read a0 操作;

  2. CPU2 会向地址总线,发送读取 a0 变量的数据的请求,此时该请求不仅会被内存收到,也会被其他 CPU 核心收到。

  3. CPU1 从地址总线得知,CPU2 发起的读取地址存在于 CPU1 Cache 里,于是 CPU1 Cache 里数据的状态会从 E(独占)变更为 S(共享);

  4. 内存收到 CPU2 发起的读取 a0 数据的请求后,就会通过数据总线将数据传递给 CPU2;

  5. 最后数据会写到 CPU2 Cache 里,且状态是 S(共享)。

其他状态的变更,我在这里就不介绍了,大家自己去网站体验下,这样会感触比较深,光听我讲也记不住。可以对照我文章中 MESI 状态转换的表格来做实验,感受下 MESI 状态到底是如何在不用加锁的情况下,是如何实现 CPU 缓存一致性的。我也把网站地址附在了「阅读原文」,点击即可访问。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

不少团队把应用切成容器后,以为节点上线会更灵活。边缘计算真到现场时,最先暴露的往往不是编排能力,而是冷启动被镜像拉取和层展开拖得过长。

关键字: 边缘计算 冷启动 CPU

在现代多核CPU的高并发编程领域,Cache伪共享是最隐蔽也最容易被忽略的性能杀手,结合我们之前深入探讨过的C++内存模型、无锁队列实现、Mutex互斥锁优化等工程实践经验,很多开发者在编写高并发多线程代码时,明明逻辑上...

关键字: CPU 伪共享

在电力电子系统全面转向数字化的当下,很多工程师都会遇到一个看似矛盾的现象:明明选用了主频足够高的数字信号控制器,算法逻辑也经过反复验证没有问题,但最终整机的稳态精度和动态性能,始终达不到理论仿真的预期。反复排查软件逻辑后...

关键字: 数字控制 CPU

机器人产业的真正分水岭,可能既不在算力大小,也不在模型参数的多寡。在各类人形机器人、自主移动机器人与智能工业系统密集亮相的当下,一个更本质的问题正在被反复追问:一台已经掌握多项技能的机器人,为什么换一个场景、换一个任务,...

关键字: ARM 物理 AI 机器人 泛化能力 CPU 运动控制

微软和亚马逊云科技最新财报传递出同一个信号:基于 Arm 架构的 CPU 已成为智能体 AI 的核心基础设施。

关键字: 云计算 CPU AI

很多现场节点一遇到吞吐瓶颈,就想把内存复制次数砍掉。边缘计算若把零拷贝只当成省一次 memcpy,很容易把新的时延和一致性问题带进主链路。

关键字: 边缘计算 零拷贝 CPU

我们已经过了仅凭演示效果来评判人工智能 (AI) 基础设施的阶段。如今,更关键的问题在于,这些能力能否以可靠、可扩展且具备成本效益的方式交付。这正是我们在设计下一代 AI 基础设施过程中,与云服务提供商、芯片合作伙伴及系...

关键字: 人工智能 CPU 自研芯片

如果我们用Arduino核心在ESP8266上写任何代码,很可能已经遇到了这个瓶颈。你写的每一行代码都运行在loop()函数内部,而loop()是协作式的——它从上到下依次执行,只有在完成所有操作后,SDK才会有机会进行...

关键字: Arduino CPU LED ESP8266

本项目记录了将一块基于STM32F407的空开发板,通过将其内部12位数模转换器(DAC)连接至PA4引脚,成功改造为功能完整的模拟信号发生器的过程。从完全零基础构建的裸机模板出发,在调试固件配置方面积累了极为丰富的学习...

关键字: CPU 信号发生器 定时器 STM32F407

核心数量提升33%、PCIe带宽提升至2倍、内存带宽提升至2.6倍,大幅强化高性能工作负载的运行。 搭载第六代AMD EPYC CPU和AMD Instinct™...

关键字: AMD CPU MICRO SUPER
关闭