MESI协议
MESI协议是一个被广泛使用的CPU缓存一致性协议。我们都知道在CPU中存在着多级缓存,缓存级别越低,容量就越小,速度也越快。有了缓存,CPU就不需要每次都向主存读写数据,这提高了CPU的运行速度。然而,在多核CPU中,低级别的缓存是单个CPU独占的:
![9af1bffe8d25cc48ba6ab94767208694.png](https://img-blog.csdnimg.cn/img_convert/9af1bffe8d25cc48ba6ab94767208694.png)
如上图所示,每个CPU核心分别拥有独立的一、二级缓存,共享了三级缓存。这就带来了缓存一致性的问题:当同一份数据同时存在于多个CPU的独立缓存中时,如何保证缓存数据的一致性?
MESI协议提供了一种方式,成功的解决了缓存一致性问题。对于缓存中的每一行,都设置一个状态位,一共有四种状态:
- M(modified):表示缓存行仅存在于当前的缓存中,并且已经被更改。在该缓存行写回到主存之前,任何其他CPU都不能读取该缓存行的内容。
- E(exclusive):表示缓存行仅存在于当前的缓存中,并且未被修改。如果有其他CPU读取该行,则转移到Shared状态;如果修改该行,则转移到Modified状态。
- S(shared):表示有多个CPU共享该缓存行,且内容未被修改。
- I(invalid):表示缓存行已失效(未被使用)。
从上述状态定义可以看出,MESI协议实际上定义了一个状态机,其中状态转移规则保证了CPU在多级缓存环境下的缓存一致性。MESI定义的状态转移规则如下所述:
除Invalid状态以外,所有状态的缓存行都可以进行读操作
从状态定义就可以看出,只有Invalid状态的缓存行内容是无效的,必须从主存读取。
只有在状态为M或E时才能进行写操作,如果当前状态为S,则其它CPU中的同一行必须转移到状态I,这是通过发送RFO(request for ownership)广播实现的
M或E状态下,缓存行都只存在于单个CPU中,S状态下多个CPU共享一行,因此必须将其他CPU的状态置为I,才能进行写操作。
除M以外的任意状态都可转移到I,M状态必须先写回到主存再丢弃
只要内容未被修改,CPU可以再任意时刻丢弃一个缓存行,否则则必须先把修改的内容写回到主存
处于M状态的缓存必须拦截其他CPU对同一行的读操作,并返回自身缓存中的数据
这可以保证所有CPU读到的都是最新的内容,这种拦截操作称为snoop,数据不需要写回到主存,直接由M状态的缓存返回,状态由M转移到S
处于S状态的缓存必须监听RFO广播,并转移到I状态
当一个CPU修改S状态的缓存时,其余的缓存必须先转移到I状态,防止并发的写操作
处于E状态的缓存必须拦截其他CPU的读操作,并转移到S状态
当有其他CPU读E状态的缓存时,状态必须由独