LLC缓存一致性保障原理

如果大家了解一点CPU的知识,应该能够了解到当前的x86架构的CPU都通过多级缓存实现内存的快速访问。目前较为流行的做法是3级缓存的设置,L1/L2为每个CPU core独享,而L3 或者LLC(last level cache)则由同一个socket上的所有物理core共享。这个时候如果考虑双路甚至多路CPU的话,由于内存中的数据有且只有一份,但多个CPU很可能在此基础上创建属于自己socket的缓存。对于内存的读访问来说,多份数据并不会影响到一致性,但一旦有一个socket上的某个core修改了数据,一致性问题则会凸显。究竟CPU是如何实现一致性保障的呢?

还是先从CPU的硬件实现来讲起。
CPU 内部有两个与内存/LLC相关的组件:CA(cache agent,负责cache内容的管理)和HA(home agent,负责内存的读写操作)。由于内存在系统视图上是一个整体,具有独立的一致性,即无论有多少物理socket,在整个系统中有且仅有一个逻辑HA。而Cache(特指LLC,下同)仅在每个socket内有效,故逻辑上CA有多个,每个socket的CA在逻辑上是独立的。根据上面描述,CA和HA之间仅存在如下几种通讯方式:CA 到其他CA、CA到HA、HA到CA。

对于CA中管理的Cache来说,分为如下的几个状态,习惯上称之为MESI或者MESIF状态机:

  • Modified:已被编辑状态,表示当前CA中的cache已经被修改且尚未同步到内存。
  • Exclusive:当前的CA已经获取了cache对应的内存写引用,但目前尚未修改。
  • Shared:CA仅获取了cache对应内存的读引用,无法直接修改内存。
  • Invalid:CA没有获取对应内存的任何引用,即系统不需要读/写对应的内存。
  • Forward:已经在最新的架构中被取消,原指CA被指派需要向其他node传输信息的状态。

这几种状态中,由于M状态的前提必须经由E状态转换而来(没有写权限就不会有被修改且尚未同步到内存的Cache数据),而是否能够取得E状态则成为了整个Cache一致性的关键。对于S状态的只读cache,只要在内存数据得到更新之后直接通知CA更新cache即可,并不存在一致性问题。I状态就更简单了,没有任何引用,自然就没有任何一致性的问题。

CA通过一个叫做snoop的方式来确保数据的一致性。假设目前有一个2Socket的系统,在默认的状况下socket 0需要update某块数据段,snoop的过程如下:

  1. Socket 0上的CA-0向HA发起获取E-0状态的请求,同时向Socket 1 的CA-1发送snooping,确保socket 1没有E以上的权限。
  2. Socket 1的CA-1在收到snooping之后检查cache中是否饮用到了对应的数据段,对应了三种可能性:
    • 没有引用,I-1状态,最简单,直接回复HA确认消息。
    • S-1状态,直接丢弃当前的数据段,向HA确认之后,等待数据更新。
    • E-1状态,说明Socket 1 有计划向此数据段写入内容,等待至数据写入后向HA回复消息,或者直接要求HA裁决先后顺序。
    • M-1状态,数据已经修改,则直接回复HA要求数据回写。
  3. HA在收到Socket 1的回复消息之后发送最新的数据段到socket 0,同时赋予socket 0的E-0权限。当然,对于M-1这种情况,HA在这个过程中就向真实的物理内存中写入数据。

这个过程的时序图表达如下:

socket snoop without cache to cache feature

其实在当前的CPU架构中支持两种形式的snooping:由CA发起的被称为socket snooping;CA请求后再由HA直接发起的被称为home snooping。简而言之,home snooping更适合对于冲突的裁决而socket snooping则具有更好的性能。同时,由于当前的Xeon CPU支持Cache to cache优化,即数据不需要回写而直接将M状态的数据段通过CA在socket之间来回传递。如果你看懂了上面的时序图,那下面的几种情况也就不难理解了。

Socket snooping with cache to cache copy

Home snooping without cache to cache

Home snooping with cache to cache copy

至于系统中多余2个socket的情形事实上跟2socket情况下没有什么太大的区别,无非多发送几个CA到CA或者HA到CA的snoop请求而已。在这里我也不再累述了。还有需要注意的是,本文介绍的几种基于snoop的一致性管理仅限于介绍“原理”,实际在工程实现上还会有各种优化方式,而事实上snoop的数量并不需要满足“每个socket都发”的条件。这里牵扯到冗余数据的问题,有机会单独开帖了。

推荐阅读:
经常会通过一些通用的测试工具测
首先,提个问题:64bit x
接到一个黑盒的case:一套双

发表评论

电子邮件地址不会被公开。 必填项已用*标注

请补全下列算式: *

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据