缓存一致性(MESI)

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

Cache一致性协议之MESI
处理器上有一套完整的协议,来保证Cache一致性。比较经典的Cache一致性协议当属MESI协议,奔腾处理器有使用它,很多其他的处理器都是使用它的变种。

单核Cache中每个Cache line有2个标志:dirty和valid标志,它们很好的描述了Cache和Memory(内存)之间的数据关系(数据是否有效,数据是否被修改),而在多核处理器中,多个核会共享一些数据,MESI协议就包含了描述共享的状态。

在MESI协议中,每个Cache line有4个状态,可用2个bit表示,它们分别是:
这里写图片描述
MESI状态

M(Modified)和E(Exclusive)状态的Cache line,数据是独有的,不同点在于M状态的数据是dirty的(和内存的不一致),E状态的数据是clean的(和内存的一致)。

S(Shared)状态的Cache line,数据和其他Core的Cache共享。只有clean的数据才能被多个Cache共享。

I(Invalid)表示这个Cache line无效。

E状态示例如下:
这里写图片描述
只有Core 0访问变量x,它的Cache line状态为E(Exclusive)。
S状态示例如下:
这里写图片描述
3个Core都访问变量x,它们对应的Cache line为S(Shared)状态。

M状态和I状态示例如下:
这里写图片描述
Core 0修改了x的值之后,这个Cache line变成了M(Modified)状态,其他Core对应的Cache line变成了I(Invalid)状态。

在MESI协议中,每个Cache的Cache控制器不仅知道自己的读写操作,而且也监听(snoop)其它Cache的读写操作。每个Cache line所处的状态根据本核和其它核的读写操作在4个状态间进行迁移。

MESI协议状态迁移图如下:
这里写图片描述
在上图中,Local Read表示本内核读本Cache中的值,Local Write表示本内核写本Cache中的值,Remote Read表示其它内核读其它Cache中的值,Remote Write表示其它内核写其它Cache中的值,箭头表示本Cache line状态的迁移,环形箭头表示状态不变。

当内核需要访问的数据不在本Cache中,而其它Cache有这份数据的备份时,本Cache既可以从内存中导入数据,也可以从其它Cache中导入数据,不同的处理器会有不同的选择。MESI协议为了使自己更加通用,没有定义这些细节,只定义了状态之间的迁移,下面的描述假设本Cache从内存中导入数据。

MESI状态之间的迁移过程如下:
这里写图片描述
AMD的Opteron处理器使用从MESI中演化出的MOESI协议,O(Owned)是MESI中S和M的一个合体,表示本Cache line被修改,和内存中的数据不一致,不过其它的核可以有这份数据的拷贝,状态为S。

Intel的core i7处理器使用从MESI中演化出的MESIF协议,F(Forward)从Share中演化而来,一个Cache line如果是Forward状态,它可以把数据直接传给其它内核的Cache,而Share则不能。

### MESI协议实现缓存一致性 #### 什么是MESI协议? MESI协议是一种用于解决多核处理器中缓存一致性问题的重要协议。该协议通过定义四种不同的状态来管理各个处理器核心中的缓存行,从而确保数据的一致性和准确性[^1]。 #### MESI协议的状态及其含义 MESI协议规定了每一条缓存行可以处于以下四种状态之一: - **Modified (M)**:表示这条缓存行的数据已经被修改过,并且只存在于当前处理器的核心缓存中;此时对应的主存中的副本已经失效。 - **Exclusive (E)**:意味着此条目仅被这一个处理器所拥有并加载到了它的私有L1 Cache里边,但是还没有做过任何更改操作。 - **Shared (S)**:当某一块内存区域同时出现在两个以上的CPU Core内部Cache Line当中,则这些Line都会标记成共享态。 - **Invalid (I)**:表明这个位置上的内容是无效的或者是不存在有效映射关系的地址空间部分[^3]。 #### 总线嗅探机制的作用 为了维持整个系统的缓存一致性MESI依赖于一种称为“总线监听”或“总线嗅探”的技术。每当某个处理单元试图访问特定地址时,它不仅会查询自身的本地存储器资源,还会向其他所有可能持有相同地址范围内的组件发送请求信号。如果检测到冲突情况——即存在另一个地方也保存着同一份资料的话,那么就会触发相应的同步动作以更新各方持有的版本至最新状态。 #### 状态转换过程示例 考虑一个多核环境中发生读取和写入事件时MESI是如何工作的例子: ##### 场景一:从主存加载未命中(Read Miss) 假设Core A想要读取位于Address X处的数据项而发现其局部Cache内并没有该项记录。这时A将发起一次全局广播询问是否有其它Cores正占有X地址对应的内容。如果没有回应则直接由Memory提供服务并将新获取的信息置为`Exclusive`模式放入自己的Cache之中。 ```python if not core_a_cache.contains(address_x): response = broadcast_read_request(address_x) if no_response(response): # No other cores have this data data_from_memory = fetch_data_from_main_memory(address_x) core_a_cache.store(data_from_memory, "Exclusive") ``` ##### 场景二:尝试独占性写入(Write Intent) 现在假定Core B打算对同样位于Address Y的位置执行写指令之前先检查是否能获得唯一控制权。为此B发出类似的探测消息给其余成员看谁手里握有所需对象以及它们各自所处的具体情形。一旦得知只有自己掌握着Y或者根本没人涉及其中就可以安全地把目标设定为`Modified`进而实施实际变更行为。 ```python if core_b_wants_to_write(address_y): responses = broadcast_invalidate_requests(address_y) all_invalidated = True for r in responses: if r.status != 'Invalid': all_invalidated = False if all_invalidated or only_core_b_has_exclusive_access(responses): core_b_cache.mark_as_modified(address_y) perform_the_write_operation() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值