缓存一致性协议

锁缓存行有一套协议叫做缓存一致性协议。缓存一致性协议有MSI、MESI、MOSI、Synapse、Firefly以及DragonProtocol等等。

MESI

MESI分别代表缓存行数据的4中状态,通过对这四种状态的切换,来达到对缓存数据进行管理的目的


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

多核缓存协同操作

假设有三个CPU-A、B、C,对应三个缓存分别是cache-a、b、c。在主内存中定义了x的引用值0


单核读取

  • CPU-A发出一条指令,从主内存中读取x
  • 从主内存通过bus读取到缓存中,此时该Cache Line修改为E状态


多核读取

  • CPU-A发出了一条指令,从主内存中读取x
  • CPU-A从主内存通过bus读取到cache-a中并将该Cache Line设置为E状态
  • CPU-B发出一条指令,从主内存中读取x
  • CPU-B试图从主内存中读取x时,CPU-A检测到了地址冲突。这时CPU-A对相应数据做出响应。此时x存在于cache-a和cache-b中,x在cache-a和cache-b中都被设置为S状态

    修改数据
  • CPU-A计算完成后发指令需要修改x
  • CPU-A将x设置为M状态(修改)并通知缓存了x的CPU-B,CPU-B将本地cache-b中的x设置为I状态(无效)
  • CPU-A对x进行赋值


同步数据

  • CPU-B发出了要读取x的指令
  • CPU-B通知CPU-A,CPU-A将修改后的数据同步到主内存时cache-a修改为E状态(独享)
  • CPU-A同步CPU-B的x,将cache-a和同步后cache-b中的x设置为S状态(共享)

MESI优化和引入的问题:各CPU缓存行的状态是通过消息传递来进行的。如果CPU0要对一个在缓存中共享的变量进行写入,首先需要发送一个失效的消息给到其他缓存了该数据的CPU,并且要等到他们的确认回执。CPU0在这段时间内都会一直处于阻塞状态,会导致各种各样的性能问题和稳定性问题。

MESI性能优化

Store Buffer

为了避免阻塞带来的资源浪费,在CPU中引入了Store Buffer。

CPU在写入共享数据时,直接把数据写入到Store Buffer中,同时发送Invalidate消息,然后继续去处理其他指令。当收到其他所有CPU发送了Invalidate Acknowledge消息时,再将Store Buffer中的数据存储到Cache Line中,最后再从Cache Line同步到主内存。


Store Buffer的问题:引入了Store Buffer后,CPU会优先从Store Buffer中读取数据,这在一些情况下会导致CPU的乱序执行,也可以认为是一种重排序,这种重排序会带来可见性问题

Store Forwarding

Write Memory Barrier

Invalidate Queue

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容