一、内存-Cache一致性的实现方式
- 写直达:把数据同时写入内存和Cache中
- 如果数据已经在Cache里面,先将数据更新到 Cache里面,再写入到内存里面
- 如果数据没有在Cache里面,就直接把数据更新到内存里面。
- 写回:发生写操作时,新的数据仅仅被写入Cache Block(缓存块)里,只有当修改过的 Cache Block (被替换)时才需要写到内存中,减少了数据写回内存的频率,提高了系统的性能
- 如果发生写操作时,数据已经在缓存块里,则把数据更新到缓存块,同时把这个缓存块标记为脏
- 如果发生写操作时,数据所对应的缓存块中存放的是别的内存地址的数据,就得检查该缓存块是不是脏的。如果是的,就把这个缓存块的数据写回内存,然后把要写的数据写入该缓存块中,同时标记为脏;如果不是,直接把数据写入该缓存块,然后再把该缓存块标记为脏就行了。
二、缓存一致性问题
问题
解决措施
- 写传播:某个CPU核心里的Cache数据更新时,必须要传播到其他核心的Cache
- 事务串行化:某个CPU核心里对数据的操作顺序,必须在其他核心看起来的顺序是一样的
三、总线嗅探
当 A 号CPU核心修改了 L1 Cache 中 i 变量的值,通过总线把这个事件⼴播通知给其他所有的核心,然后每个 CPU 核心都会监听总线上的⼴播事件,并 检查是否有相同的数据在自己的 L1 Cache里面,如果 B 号 CPU 核心的 L1 Cache 中有该数据,那么也需要把该数据更新到自己的 L1 Cache。
总线嗅探⽅法很简单, CPU 需要每时每刻监听总线上的⼀切活动,但是不管别的核⼼的 Cache 是否缓存相同的数据,都需要发出⼀个⼴播事件,这⽆疑会加重总线的负载
四、MESI协议
MESI协议
- Modified:已修改状态
- Exclusive:独占状态
- Shared:共享状态
- Invalidated:已失效状态
四种状态描述
- 已修改状态:代表该缓存块上的数据已经被更新过,但是还有没有写到内存里。
- 已失效状态:代表该缓存块里的数据已经失效,不可以读取该状态的数据。
- 独占状态:数据只存储在⼀个 CPU核心的 Cache里,而其他 CPU 核心的 Cache 没有该数据。如果要向独占的 Cache 写数据,就可以直接自由地写入,而不需要通知其他 CPU 核心,因为只有你这有这个数据,就不存在缓存⼀致性的问题了,于是就可以随便操作该数据。
在独占状态下的数据,如果有其他核心从内存读取了相同的数据到各自的 Cache ,那么这个时候,独占状态下的数据就会变成共享状态。 - 共享状态:代表着相同的数据在多个 CPU 核心的 Cache里都有,所以当我们要更新 Cache里面的数据的时候,不能直接修改,而是要先向所有的其他 CPU 核心广播⼀个请求,要求先把其他核心的 Cache 中对应的 Cache Line 标记为无效状态,然后再更新当前Cache里面的数据。