多核处理器下的缓存一致性解决方案-MESI协议

转载自 https://www.cnblogs.com/z00377750/p/9180644.html

1、问题根源

CPU Cache: 解决的是内存访问速度和 CPU 的速度差距太大的问题。
多核 CPU: 在主频难以提升的时候,通过增加 CPU 个数来提升 CPU 的吞吐率的办法。
我们把多核和 CPU Cache 两者一结合,就给我们带来了一个新的挑战。因为 CPU 的每个核各有各的缓存,互相之间的操作又是各自独立的,就会带来缓存一致性(Cache Coherence) 的问题

多CPU系统的高速缓存结构
图1:高速缓存结构
如上图所示 CPU Cache 中,L1 和 L2 Cache 都是 CPU 独有的,而 L3 和 DRAM 则是共有的。如果 CPU-1 更新了自己的 L1 或 L2 Cache 没有更新主存,或者 CPU-1 写的同时 CPU-2 并发读,则会造成 CPU-1 和 CPU-2 的数据不一致。无论是直接写还是写回策略都没有解决这个问题。

2、解决方案

要解决缓存一致性问题,首先要解决的是多个 CPU 之间的数据传播问题。

总线嗅探(Bus Snooping): 最常见的一种解决多核 CPU 数据广播问题的方案。本质上就是把所有的对Cache的读写请求都通过总线(Bus) 广播给所有的 CPU 核心,然后让各个核心去“嗅探”这些请求,再根据本地的情况进行响应。
MESI 协议: 基于总线嗅探机制的缓存一致性协议,MESI 协议也是在 Pentium 时代被引入到 Intel CPU。

写失效(Write Invalidate) 协议: 在写失效协议里,在这个 CPU 写入 Cache 后,它会去广播一个“失效”请求给其他所有 CPU。其他 CPU 如果也存在这个缓存行,直接标记成失效状态。MESI 协议使用的就是写失效协议。

MESI 协议详解

MESI(Modified Exclusive Shared Or Invalid)(也称为伊利诺斯协议,是因为该协议由伊利诺斯州立大学提出)是一种广泛使用的支持写回策略的缓存一致性协议。

MESI协议中的状态
CPU中每个缓存行(caceh line)使用4种状态进行标记(使用额外的两位(bit)表示):

M: 被修改(Modified)

该缓存行只被缓存在该CPU的缓存中,并且是被修改过的(dirty),即与主存中的数据不一致,该被修改过的缓存行需要在未来的某个时间点(允许其它CPU读取主存中相应地址之前)写回(write back)主存。

当被写回主存之后,该缓存行的状态会变成独享(exclusive)状态。

E: 独享的(Exclusive)

该缓存行只被缓存在该CPU的缓存中,它是未被修改过的(clean),与主存中数据一致。该状态可以在任何时刻当有其它CPU读取该内存时变成共享状态(shared)。

同样地,当CPU修改该缓存行中内容时,该状态可以变成Modified状态。

S: 共享的(Shared)

该状态意味着该缓存行可能被多个CPU缓存,并且各个缓存中的数据与主存数据一致(clean),当有一个CPU修改该缓存行中,其它CPU中该缓存行可以被作废(变成无效状态(Invalid))。

I: 无效的(Invalid)

该缓存是无效的(可能有其它CPU修改了该缓存行)。

MESI状态转换图:
在这里插入图片描述
状态之间的相互转换关系也可以使用下表进行表示

在这里插入图片描述

操作

在一个典型系统中,可能会有几个缓存(在多核系统中,每个核心都会有自己的缓存)共享主存总线,每个相应的CPU会发出读写请求,也都会执行嗅探协议,而缓存的目的是为了减少CPU读写共享主存的次数。

一个缓存除在Invalid状态外都可以满足cpu的读请求,一个Invalid的缓存行必须从主存中读取(变成S或者 E状态)来满足该CPU的读请求。

一个写请求只有在该缓存行是M或者E状态时才能被执行,如果缓存行处于S状态,必须将其它缓存中该缓存行变成Invalid状态 (写失效协议)。该操作经常作用广播的方式来完成,例如:RequestFor Ownership (RFO)

一个处于M状态的缓存行必须时刻 嗅探总线
监听其他 核心 试图读该缓存行的操作,这种操作在进行之前 必须先将该缓存行写回主存并将状态变成S状态。
监听其他 核心 试图写该缓存行的操作,这种操作在进行之前 必须先将该缓存行写回主存(因为其他核心的缓存行是 I 状态,会读主存)并将状态变成 I状态。

一个处于S状态的缓存行也必须 嗅探总线
监听其它 核心 写该缓存行的操作,一旦有这种操作,将该缓存行变成 I 状态
监听本 核心 写该缓存行的操作,一旦有这种操作,将该缓存行变成 M 状态

一个处于E状态的缓存行也必须 嗅探总线
监听其它 核心 读主存中该缓存行的操作,一旦有这种操作,该缓存行需要变成 S 状态。
监听其它 核心 写该缓存行的操作,一旦有这种操作,该缓存行需要变成 I 状态。
监听本 核心 写该缓存行的操作,一旦有这种操作,该缓存行需要变成 M 状态。

对于M和E状态而言总是精确的,他们在和该缓存行的真正状态是一致的。而S状态可能是非一致的,即 如果a缓存将处于S状态的缓存行作废了,状态修改为I,而另一个缓存B实际上就变成独享该缓存行的状态,应该将状态修改为E,但是B缓存却不会修改为E状态,这是因为其它a缓存不会广播它作废掉该缓存行的通知,同样由于缓存并没有保存该缓存行的copy的数量,因此(即使有这种通知)也没有办法确定自己是否已经独享了该缓存行。

从上面的意义看来E状态是一种投机性的优化:如果一个CPU想修改一个处于S状态的缓存行,总线事务需要将所有该缓存行的copy变成Invalid状态,而修改E状态的缓存不需要使用总线事务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值