MESI缓存一致性协议
MESI缓存一致性协议
Shio⚠️⚠️⚠️ 注意!!! 本文还未完成,⚠️⚠️⚠️
目前大多数PC的CUP都是多核
我们知道根据摩尔定律, CPU性能每隔18个月就会翻一倍(即使在10年后逐渐失效)
在经典的冯诺依曼体系中, 存储器和计算器的IO导致的性能低下已经越发的突出
由此,大多CPU都会存在缓存这一中间设备, 利用局部性原理, 将热点数据存储在缓存中
目前大多设备为三级缓存
其中L1, L2缓存为单个CPU私有(可能由于CPU架构而不同), L3缓存为共享, 但这并不是本节讨论的重点,接下来, 我们直接将缓存抽象为每个CPU核心所私有的
缓存的引入,极大的降低了IO效率, 提升了CPU整体的效率,但是多核架构下, 引入缓存会出现一致性问题
什么时一致性问题呢?
我们举个最简单的例子
CPU公有两个核心
P1 P2
现在内存中有一个全局变量 n = 1, 被两个核心共享
目前两个核心缓存都不存在这个全局变量(缓存引入后, CPU只直接操作缓存, 操作内存需要先读入缓存再写入缓存, 但是写入的时间并不确定)
假设 P1 P2的目的都是让全局变量加1, 那么我们预期的结果是 最后 n = 3
但是下面的执行流程会得出不一样的结果
P1 读入缓存 n = 1. 再缓存中+1 n = 2
之后P1还未把缓存写入内存, P2开始了操作
P2 读入缓存 n = 1. 再缓存中+1 n = 2
P1 写入内存 n = 2 覆盖了原本内存中的n = 1
P2 写入内存 n = 2 覆盖了原本内存中的n = 2
最后内存中的值是n = 2
这就是我们所说的一致性问题, 因为副本的更新不能即时的刷入内存中导致的(操作的原子性)
那么我们直接让每个操作都原子性不就好了?
于是引入了第一种解决方案
锁总线, 每次操作只能有一个核心执行, 这显然是极其低效的, 直接PASS
总线嗅探机制(其实还有基于目录的缓存一致性协议)
写失效(Write Through)
写更新(Write Back)