当前位置:首页 > > 处芯积律


缓存一致性简介

对于单核CPU来说,不存在数据一致性问题;然而对于多核系统来说,不同CPU上的cache和ram可能具有同一个数据的多个副本。这就会导致数据观察者(CPU/GPU/DMA)能看到的数据不一致。

因此,维护cache一致性就非常有必要。维护cache一致性的关键是需要跟踪每个Cache Line的状态,并且根据读写操作和总线上相应的传输内容来更新Cache Line在不同CPU核心上的Cache Hit状态。

维护cache一致性有软件和硬件两种方式。现在大多数处理器都采用硬件来维护。在处理器中通过cache一致性协议来实现,这些协议维护了一个有限状态机,根据存储器读写指令/总线上的传输内容,进行状态迁移/相应的cache操作来维护cache一致性。

cache一致性协议本质上是如果通过硬件锁定cache line的协议,以cache line为粒度,提高效率。

MESI协议

MESI协议(Write-Once总线监听协议),MESI这四个字母分别代表Modify、Exclusive、Shared和Invalid。Cache Line的状态必须是这四个中的一种。前三种状态均是数据有效下的状态。Cache Line有两个标志-脏(dirty)和有效(valid)。脏代表该数据和内存不一致。只有干净的数据才能被多个Cache Line共享。

MESI状态描述如下:


状态 描述 监听任务
M 修改(Modify) 该缓存行有效,数据被修改了,和内存中的数据不一致,该数据只存在于本缓存行中 缓存行必须时刻监听所有试图读该缓存行相对应的内存的操作,其他缓存须在本缓存行写回内存并将状态置为E之后才能操作该缓存行对应的内存数据
E 独享、互斥(Exclusive) 该缓存行有效,数据和内存中的数据一致,该数据只存在于本缓存行中 缓存行必须监听其他缓存读主内存中该缓存行相对应的内存的操作,一旦有这种操作,该缓存行需要变成S状态
S 共享(Shared) 该缓存行有效,数据和内存中的数据一致,数据同时存在于其他缓存中 缓存行必须监听其他缓存是该缓存行无效或者独享该缓存行的请求,并将该缓存行置为I状态
I 无效(Invalid) 该缓存行数据无效


对一条cache line的操作有如下几种:


操作类型 描述
本地读(local read) 本地CPU读取Cache Line
本地写(local write) 本地CPU更新Cache Line
远程读(Remote read) 来自其他cpu的读cache信号
远程写(Remote write) 来自其他cpu的写cache信号


MESI状态及变化

M状态跳变

如果cache line当前状态为M,那么下一个状态有以下几种情况:


当前状态

操作

行为

下一个状态

M

本地读(local read)

从该cache line中读数据,状态不变

M

M

本地写(local write)

往该cache line中写数据,状态不变

M

M

远程读(Remote read)

如果有其他cpu来读该cache line必须完成如下操作:

  1. 该cache line先写到内存中;

  2. 其他cpu读内存中的数据;

  3. 该cache line中的数据同时存在于多个cpu,状态修改为共享S;

S

M

远程写(Remote write)

如果有其他cpu来写该cache line必须完成如下操作:

  1. 该cache line先写到内存中;

  2. 其他cpu读内存中的数据;

  3. 其他cpu修改读到的cache line数据;

  4. 该cache line中的数据在其他cpu中被修改了,状态必须修改为无效I;

I

E状态跳变

如果cache line当前状态为E,那么下一个状态有以下几种情况:


当前状态

操作

行为

下一个状态

E

本地读(local read)

从该cache line中读数据,状态不变

E

E

本地写(local write)

往该cache line中写数据,状态改变成修改过:M

M

E

远程读(Remote read)

如果有其他cpu来读该cache line必须完成如下操作:

  1. 其他cpu读内存中的数据;

  2. 该cache line中的数据同时存在于多个cpu,状态修改为共享S;

S

E

远程写(Remote write)

如果有其他cpu来写该cache line必须完成如下操作:

  1. 其他cpu读内存中的数据;

  2. 其他cpu修改读到的cache line数据;

  3. 该cache line中的数据在其他cpu中被修改了,状态必须修改为无效I;

I

S状态跳变

如果cache line当前状态为S,那么下一个状态有以下几种情况:


当前状态

操作

行为

下一个状态

S

本地读(local read)

从该cache line中读数据,状态不变

S

S

本地写(local write)

往该cache line中写数据,状态修改为M;

其他拥有该cache line备份的cpu的cache都必须置为无效状态I

M

S

远程读(Remote read)

如果有其他cpu来读该cache line必须完成如下操作:

  1. 由于cache line和内存中数据一样,其他cpu读内存中的数据;

  2. 该cache line中的数据同时存在于多个cpu,状态仍然为共享S;

S

S

远程写(Remote write)

如果有其他cpu来写该cache line必须完成如下操作:

  1. 由于cache line和内存中数据一样,其他cpu读内存中的数据;

  2. 其他cpu修改读到的cache line数据;

  3. 该cache line中的数据在其他cpu中被修改了,状态必须修改为无效I;

I

I状态跳变

如果cache line当前状态为S,那么下一个状态有以下几种情况:


当前状态

操作

行为

下一个状态

I

本地读(local read)

从内存中读cache line,存在三种情况:

  1. 如果该cache line不存在于其他cpu中,那么状态改变成E;

  2. 如果该cache line存在于其他cpu的cache中,并且其他cpu中没有修改这个cache line,那么状态改变为S;

  3. 如果该cache line存在于其他cpu的cache中,并且其他cpu中修改了这个cache line,那么只会有一个cpu中保留了这个cache line并且状态为M, 首先这个cpu必须把cache line写回内存; 然后本地cpu读该cache line,两个cpu中的cache line状态都变成S;

S或E

I

本地写(local write)

从内存中读cache line,然后修改该cache line,状态修改为M;

如果其他cpu存在该cache line的备份,那么这些备份必须修改为无效I;

M

I

远程读(Remote read)

本地cache为无效状态,其他cpu读不影响本地状态;

I

I

远程写(Remote write)

本地cache为无效状态,其他cpu读不影响本地状态;

I

MESI状态机

MESI协议多个状态的最终状态机如下:

MESI协议的缺点

如果由特定块上的各种高速缓存执行连续读取和写入操作,则每次都必须将数据刷新到总线上。因此,主存储器将在每次冲洗时拉动它并保持清洁状态。但这不是一项要求,只是由于MESI的实施而导致的额外开销。MOESI协议克服了这一挑战。

MOESI协议

MOESI协议引入了一个O(Owned)状态,并在MESI协议的基础上,进行了重新定义了S状态,而E、M和I状态和MESI协议的对应状态相同。

  1. O位。O位为1表示在当前Cache 行中包含的数据是当前处理器系统最新的数据拷贝,而且在其他CPU中一定具有该Cache行的副本,其他CPU的Cache行状态为S。如果主存储器的数据在多个CPU的Cache中都具有副本时,有且仅有一个CPU的Cache行状态为O,其他CPU的Cache行状态只能为S。与MESI协议中的S状态不同,状态为O的Cache行中的数据与存储器中的数据并不一致。

  2. S位。在MOESI协议中,S状态的定义发生了细微的变化。当一个Cache行状态为S时,其包含的数据并不一定与存储器一致。如果在其他CPU的Cache中不存在状态为O的副本时,该Cache行中的数据与存储器一致;如果在其他CPU的Cache中存在状态为O的副本时,Cache行中的数据与存储器不一致。


MOESI协议优点

MOESI协议是MESI协议的一个更复杂的版本,它避免了当另一个处理器尝试读取时,需要将脏缓存行(dirty cache line)写回主内存的情况。相反,Owned状态允许处理器直接向其他处理器提供修改后的数据。当两个CPU之间的通信延迟和带宽显著优于主内存时,这种方式是有益的。一个例子是具有每核L2缓存的多核CPU。

尽管MOESI协议能够快速地从缓存中共享脏缓存行,但它不能快速共享干净的缓存行。如果一个缓存行相对于内存是干净的并且处于共享状态,那么对该缓存行的任何监听请求都将从内存中填充,而不是从缓存中。

如果处理器希望写入一个Owned缓存行,它必须通知其他正在共享该缓存行的处理器。根据具体实现,它可能只是告诉它们使它们的副本失效(将其自己的副本移动到Modified状态),或者它可能告诉它们用新内容更新它们的副本(保留其自己的副本在Owned状态)。

MOESI协议相比于MESI协议的优点是,当在其他CPU cache中发生Read hit时候,不需要将数据写回存储器,而是将数据从一个CPU直接传到另一个CPU,提高了cache利用率。

MOESI具体状态跳变这里就不重复的推演了,有兴趣的可以自己试一下。

ACE 是按照MOESI协议来实现的。

后记

技术很重要,技术背后的思想更重要!

技术背后的某些思想就是你解决以后问题的钥匙。我的文章可能一篇中知识点不太多,但是力求让你能深入理解,为你进阶打下基础。如果有一点点收获,也算是我对中国芯片行业的一点点贡献吧。


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭