路漫漫其修远兮
吾将上下而求索

系统学习:cache之多核一致性

MSI协议

大部分的多核处理器都是采用write invalidate的做法,具体的实现取决于不同的cache一致性协议,但其中最基础的是MSI,"M", "S", "I"这3个字母代表了一个cache line可能的三种状态,分别是Modified, Shared和Invalid。

当一些CPU从内存读取了数据到自己的cache line,此时这些CPU中的这些cache line中的数据都是一样的,和内存对应位置的数据也是一样的,cache line都处于shared状态。

图 1 – S与S共存

接下来P2将自己cache line的数据更改为13,P2的这条cache line就变为modified状态(S–>M),其他CPU的cache line就变为invalid状态(S–>I)。

图 2 – M与I共存

然后如果P1试图读取这条cache line中的数据,由于是invalid状态,于是将触发cache miss(细分的话叫read miss),那么P2将会把自己cache line的数据写回(writeback)到内存,供P1从内存读取,之后P1和P2的cache line都将回到shared状态(I–>S, M–>S)。

图 3 – S与I共存

这里包含着一个前提,就是某个CPU在自己的cache中,对内存某个位置对应的invalid cache line访问触发的cache miss,其他拥有这个内存位置对应的cache line的CPU都能识别,这个前提自然也属于MSI协议实现的一部分。

在上面图2的状态中,如果P1不是读取,而是写入这条cache line,那么也将触发cache miss(不过这次是write miss),P1的cache line将变为modified状态(I–>M),而P2的cache line将变为invalid状态(M–>I)。

图 4

无论什么时刻,在某个内存位置和它对应的所有cache line中,至多有一个CPU的cache line可以处于modified状态,代表着最新的数据。其他CPU中cache line中的数据过时没关系,把状态标记为失效就可以了。

至此,MSI协议中三种状态之间的转换就基本展现完了,这三种状态中的每两种,都可以在一定场景下相互转换(共6种)。此外,在cache line处于shared状态时,读这条cache line的操作不会改变原来的状态,而在cache line处于modified状态时,写这条cache line的操作也不会改变状态。整个状态转换关系如下图所示(共8种),其中"remote"代表是其他CPU进行的cache line操作。

各个CPU中,对应内存同一位置的cache line,可以同时处于shared状态(图 1),可以一个处于modified状态,其他处于invalid状态(图 2与图 4),还可以一部分处于shared状态,另一部分处于invalid状态(图 3)。允许的状态共存组合一共有4种:

上图右下角的全为invalid状态的情况,可由总线上其他不具有cache的设备直接更改内存造成,比如从DMA设备向内存的数据传输,将导致内存里的数据比所有CPU的cache line中的数据都要新,此时cache一致性的维护将可能需要软件的参与。

在MSI的基础上,加上一种表示排他性独占的(E)xclusive状态,就成了经典的MESI协议。现代处理器采用的协议基本都衍生自MSI/MESI,但往往更加复杂。比如在ARM为降低CPU功耗推出的big.LITTLE技术中,CPU被划分到了big cluster和LITTLE cluster中,要维护不同cluster的CPU之间的cache一致性就需要做更多的工作,而ARM采用的ACE协议就能较好地解决big.LITTLE技术带来的cache一致性问题。

不管是什么样的维护cache一致性的协议,其设计的目标都是使总线的通信量尽可能地小,同时优化某些频繁执行的操作。


参考:https://zhuanlan.zhihu.com/p/95435168

未经允许不得转载:江哥架构师笔记 » 系统学习:cache之多核一致性

分享到:更多 ()

评论 抢沙发

评论前必须登录!