带你了解缓存一致性协议 MESI

1 CPU Cache 结构缓存

CPU 在执行指令的时候须要从 memory 中获取指令和须要的数据,可是 CPU 的速度要比 memory 快不少,这就致使了 CPU 大部分时间都不是在作运算上而是用在了和 memory 进行数据的 I/O 过程当中,这样性能是很低的。这就致使了 CPU cache 的产生,CPU 将数据从 memory 读取到 cache 中,在 cache 中对数据进行读写的速度是很快的,这样就提升了性能。CPU 执行运算时不可能须要某一个数据就去读取一次,这样就增长了 I/O 的频率,致使性能低下。因此会一次性读取一块内存的数据存放到 cache 中, 这个块称为 “cache line” , cache line 的大小是固定的, 一般是 2 的 N 次方,在 16 ~ 256 byte 不等。当某个数据首次被 CPU 访问时, cache 中不存在,这称为 “cache miss” (或 “startup” 或 “warmup” cache miss)。这意味着 CPU 必需要去 memory 中读取该数据,这时候 CPU 必须等待(stalled)。当 cache 装满后,后续的 cache miss 须要置换 cache 中现有的数据,这样的 cache miss 被称为 “capacity miss” 。若是随后又访问了被替换的 cache line ,这时的 cache miss 被称为 “associativity miss” 。 安全

当 CPU 写数据的时候,须要保证该数据在多个 CPU cache 之间的一致性。在写以前必须先让其余 CPU cache 中的该数据失效,以后才能够安全的写数据。若是这个数据已经存在于要执行写指令的 CPU cache 中,可是是 read only 的,这个过程被称为 "write miss" ,一旦其余 CPU cache 中的该数据都失效后,该 CPU 能够不断的写或读其 cache 中的数据。若是另外某一个 CPU 尝试访问该数据,会造成一次 cache miss ,这时称为 “communication miss” 。由于这一般是多个 CPU 之间使用缓存通讯形成的。性能

2. 缓存一致性协议spa

缓存一致性协议用于管理多个 CPU cache 之间数据的一致性,这些协议十分复杂,在这里咱们仅讨论 MESI 协议的四种状态。blog

M : modified内存

E : exclusiveci

S : sharedrem

I : invalidit

协议在每个 cache line 中维护一个两位的状态 “tag” ,这个 “tag” 在 cache line 的物理地址或者数据后。io

modified 状态的 cache line 是因为相应的 CPU 进行了写操做,同时也表示该数据不会存在于其余 CPU 的 cache 中。也就说明这个最新的数据目前是被执行写操做的 CPU cache line 独占的。由于如此当前 cache 须要对该数据负责,好比将该数据传递给其余 CPU cache ,或者是将该数据写回到 memory 中。而这些操做都须要在 reuse cache line (置换)以前完成。

exclusive 状态和 modified 状态相似,区别是 CPU 尚未修改 cache line 中的数据。在 exclusive 状态下 CPU 能够不通知其余 CPU 而直接 cache line 进行操做。也就是说 exclusive状态是该 CPU 对这个数据的独占。此时因为 memory 中和 cache line 中的数据都是最新的,因此不须要对 exclusive 状态的 cache line 执行写回 memory 的操做就能够直接 reuse。

shared 状态的 cache line ,其数据可能在一个或者是多个 CPU cache 中,此时 CPU 不能直接修改 cache line 中的数据,而是须要先通知其余 CPU cache 。和 exclusive 同样, shared 状态的 cache line 对应的 memory 中的数据也是最新的,所以也能够直接 reuse cache line。

invalid 状态时 cache line 是空的。当新的数据要进入 cache 的时候优先选择 invalid 的 cache line ,之因此如此是由于若是选中其余状态的 cache line 会涉及到 cache line 中数据的置换 , 而以后若是这个被替换的数据被访问到会形成 cache miss ,这样形成很大的开销。

 image.png

3 MESI 协议消息

  1. Read。"read" 消息用来获取指定物理地址上的 cache line 数据。
  2. Read Response。该消息携带了 “read” 消息所请求的数据。read response 可能来自于 memory 或者是其余 CPU cache。
  3. Invalidate。该消息将其余 CPU cache 中指定的数据设置为失效。该消息携带物理地址,其余 CPU cache 在收到该消息后,必须进行匹配,发如今本身的 cache line 中有该地址的数据,那么就将其从 cahe line 中移除,并响应 Invalidate Acknowledge 回应。
  4. Invalidate Acknowledge。该消息用作回应 Invalidate 消息。
  5. Read Invalidate。该消息中带有物理地址,用来讲明想要读取哪个 cache line 中的数据。这个消息还有 Invalidate 消息的效果。其实该消息是 read + Invalidate 消息的组合,发送该消息后 cache 指望收到一个 read response 消息。
  6. Writeback。 该消息带有地址和数据,该消息用在 modified 状态的 cache line 被置换时发出,用来将最新的数据写回 memory 或其余下一级 cache 中。

4 MESI状态图

根据 MESI 协议消息的发送和接收或者是对数据的读写,cache line 的状态会在 modified , exclusive , shared , invalid 之间进行转换。

  1. cache 经过 writeback 将数据回写到 memory 或者下一级 cache 中。这时候状态由 modified 变成了 exclusive 。
  2. cpu 直接将数据写入 cache line ,致使状态变为了 modified 。
  3. CPU 收到一个 read invalidate 消息,此时 CPU 必须将对应 cache line 设置成 invalid 状态 , 而且响应一个 read response 消息和 invalidate acknowledge 消息。
  4. CPU 须要执行一个原子的 readmodify-write 操做,而且其 cache 中没有缓存数据。这时候 CPU 就会在总线上发送一个 read invalidate 消息来请求数据,并试图独占该数据。CPU 能够经过收到的 read response 消息获取到数据,并等待全部的 invalidate acknowledge 消息,而后将状态设置为 modifie 。
  5. CPU须要执行一个原子的readmodify-write操做,而且其local cache中有read only的缓存数据(cacheline处于shared状态),这时候,CPU就会在总线上发送一个invalidate请求其余cpu清空本身的local copy,以便完成其独自霸占对该数据的全部权的梦想。一样的,该cpu必须收集全部其余cpu发来的invalidate acknowledge以后才能更改状态为 modified。
  6. 在本cpu独自享受独占数据的时候,其余的cpu发起read请求,但愿获取数据,这时候,本cpu必须以其local cacheline的数据回应,并以read response回应以前总线上的read请求。这时候,本cpu失去了独占权,该cacheline状态从Modified状态变成shared状态(有可能也会进行写回的动做)。
  7. 这个迁移和f相似,只不过开始cacheline的状态是exclusive,cacheline和memory的数据都是最新的,不存在写回的问题。总线上的操做也是在收到read请求以后,以read response回应。
  8. 若是cpu认为本身很快就会启动对处于shared状态的cacheline进行write操做,所以想提早先霸占上该数据。所以,该cpu会发送invalidate敦促其余cpu清空本身的local copy,当收到所有其余cpu的invalidate acknowledge以后,transaction完成,本cpu上对应的cacheline从shared状态切换exclusive状态。还有另一种方法也能够完成这个状态切换:当全部其余的cpu对其local copy的cacheline进行写回操做,同时将cacheline中的数据设为无效(主要是为了为新的数据腾些地方),这时候,本cpu不劳而获,直接得到了对该数据的独占权。
  9. 其余的CPU进行一个原子的read-modify-write操做,可是,数据在本cpu的cacheline中,所以,其余的那个CPU会发送read invalidate,请求对该数据以及独占权。本cpu回送read response”和“invalidate acknowledge”,一方面把数据转移到其余cpu的cache中,另一方面,清空本身的cacheline。
  10. cpu想要进行write的操做可是数据不在local cache中,所以,该cpu首先发送了read invalidate启动了一次总线transaction。在收到read response回应拿到数据,而且收集全部其余cpu发来的invalidate acknowledge以后(确保其余cpu没有local copy),完成整个bus transaction。当write操做完成以后,该cacheline的状态会从Exclusive状态迁移到Modified状态。
  11. 本CPU执行读操做,发现local cache没有数据,所以经过read发起一次bus transaction,来自其余的cpu local cache或者memory会经过read response回应,从而将该 cache line 从Invalid状态迁移到shared状态。
  12. 当cache line处于shared状态的时候,说明在多个cpu的local cache中存在副本,所以,这些cacheline中的数据都是read only的,一旦其中一个cpu想要执行数据写入的动做,必须先经过invalidate获取该数据的独占权,而其余的CPU会以invalidate acknowledge回应,清空数据并将其cacheline从shared状态修改为invalid状态。

相关文章
相关标签/搜索