写回策略的一致性MESI协议
书接上回,由于MSI协议里面的S状态不区分拷贝是否唯一,所以MSI协议有一个天生的缺陷,会影响诸如顺序执行程序等几乎没有数据共享的程序在执行时的性能。要解决这个问题,需要引入另一个状态。
与MSI协议相同,处理器的缓存请求包含:
PrRd,处理器请求从缓存块中读出;
PrWr,处理器请求像缓存块中写入。
总线侦听的请求包含:
BusRd,总线侦听到一个来自另一个处理器的读出缓存请求;
BusRdX,总线侦听到一个来自另一个处理器的“读独占”(或者是写)缓存请求;
BusUpgr,总线侦听到一个要向其它处理器缓存已经拥有的缓存块上写入的请求;
Flush,总线侦听到一个缓存块被另一个处理器写回到主存的请求。
FlushOpt,总线侦听到一整块缓存块被放至总线已提供给另一个处理器。
每一个缓存块的状态包含:
Modified(M),缓存块有效,并且其数据与主存中的原始数据不同,这个缓存块是“dirty”的;
Eclusive(E),缓存块是干净有效且唯一的;
Shared(S),缓存块是有效干净的,但在多个缓存有拷贝;
Invalid(I),缓存块无效。
缓存一致性控制器是如何知道加载进缓存的块应该是E还是S状态。我们需要引入一条新的总线,C总线。当存在至少一份缓存拷贝时,C总线为高电平,否则缓存块唯一,C总线为低电平。
假设使用写分配和写无效的缓存一致性策略。MESI一致性协议的状态转换如下图。
图1 写回缓存的MESI一致性协议状态转换图
当缓存块处于I状态时,处理器发出读请求,在总线上产生BusRd请求。内存控制器响应BusRd,将所需要的块从内存中取出。其它的侦听器会侦听到该请求并检查它们的缓存来判断是否拥有该拷贝。如果发现拷贝,即C总线为高,取回的块放在请求者的缓存上并置为S状态;否则被置为E状态。处理器发出写请求,触发BusRdX,其它缓存无效自己的拷贝,请求者获得该块后状态变为M。
如果缓存块处于E状态,处理器发出读/写请求都不会触发总线事务,因为E状态表示缓存块是干净有效且唯一的,这是与MSI协议最大的不同。
如果缓存块处于S状态,当处理器发出读请求后会马上得到数据,并不触发总线事务。当处理器发出写请求,由于该块还在其它地方有拷贝,因此必须通知拥有拷贝的缓存,也就是触发了BusUpgr。
如果缓存块处于M状态,说明该缓存块有效,并且没有其它的拷贝。因此处理器的读/写请求都不会产生总线事务,也不会改变缓存块状态。
再来看侦听端的情况。如果缓存块处于I状态,说明缓存块无效。即使侦听到总线上的事务也不会影响它的状态。
如果缓存块处于E状态,当侦听到其它处理器发出的BusRd时,说明其它处理器遇到了读缺失并且需要加载该缓存块,因此自己拥有的拷贝就不唯一了,需要改变状态到S,同时还要产生FlushOpt来把自己的拷贝分享给请求者。这种缓存到缓存的传输大大降低了请求者从主存读取数据的延迟。如果侦听到BusRdX,说明其它处理器要求独占这个缓存块,因此自己的状态需要变成I。
如果缓存块处于S状态,当侦听到BusRd,说明其它处理器遇到了读缺失,自己的状态不需要改变,但是拥有拷贝的某一个处理器需要提供缓存到缓存的传输。当侦听到BusRdX,需要清空块并且无效自己的拷贝。当侦听到BusUpgr,直接无效拷贝。
如果缓存块处于M状态,说明该缓存块在整个系统里面是唯一有效的,当侦听到BusRd或BusRdX时都需要清空块,区别是其它处理器的请求是独占时要无效自己的拷贝,状态变为I,否则只是变为S。
由于引入了E状态,MESI协议可以消除MSI协议的读-写次序操作引发的的两次总线事务,避免了性能损耗。但是MESI仍然有一个潜在的问题。当一个缓存块被多个处理器连续读写时,每一个操作都会触发干预,需要拥有者清空缓存块。也就说S状态需要缓存块是“干净”的,这样就需要频繁更新主存,从而消耗很大的带宽。
如果能允许多个缓存之间共享“脏”块而不再频繁更新主存,那么就能解决这个问题了。
写回策略的一致性MOESI协议
与MSI协议相同,处理器的缓存请求包含:
PrRd,处理器请求从缓存块中读出。
PrWr,处理器请求像缓存块中写入。
总线侦听的请求包含:
BusRd,总线侦听到一个来自另一个处理器的读出缓存请求。
BusRdX,总线侦听到一个来自另一个处理器的“读独占”(或者是写)缓存请求。
BusUpgr,总线侦听到一个要向其它处理器缓存已经拥有的缓存块上写入的请求。
Flush,总线侦听到一个缓存块被另一个处理器写回到主存的请求。
FlushOpt,总线侦听到一整块缓存块被放至总线已提供给另一个处理器。
FlushWB,侦听到一整块缓存被另一个处理器写回主存,并且这里不是缓存到缓存之间的传输。
每一个缓存块的状态包含:
Modified(M),缓存块有效,并且其数据与主存中的原始数据不同,这个缓存块是“脏”的。
Eclusive(E),缓存块是干净有效且唯一的。
Owned(O),缓存块是有效的,可能是“dirty”,也可能有多份拷贝。但是,当存在多份拷贝时,只能有一个是O状态,其他拷贝都是S状态。
Shared(S),缓存块是有效干净的,但在多个缓存有拷贝
Invalid(I),缓存块无效。
提出O状态的一个想法是,当一个缓存块被多个处理器缓存共享,其值被允许与主存中的对应值不同。其中一个缓存块被设定为块的所有者并将状态置为O,其它备份则为S。O的出现简化了缓存到缓存的数据传输。比如,当侦听到一个BusRd时,可以让所有者通过FlushOpt来提供数据而其它控制器没有任何操作。
依然假设是使用写分配和写无效的缓存一致性策略。MOESI一致性协议的状态转换如下图,为了显示清楚,分为了上下两部分,大家可以自己分析一下。
图2 写回缓存的MOESI一致性协议状态转换图
领取专属 10元无门槛券
私享最新 技术干货