Cache coherence in shared-memory architectures

450 阅读4分钟

问题引入

在多核处理器模式下,多核共享内存。

图片.png

CPU缓存嗅探技术(snoop)

图片.png

图片.png

总线仲裁(bus arbitration)保证只有一个CPU在使用总线。

选择update还是invalidate?

总线是宝贵的资源,总线带宽是独享资源。

更新的方式,需要将其他CPU的cache都更新。在总线上,存在广播风暴。即使其他CPU没有缓存该数据,也会促发广播操作,而invalidate方式可以不用发送任何消息。

invalidate可以有效降低总线带宽

MESI

  • mesi协议尽量降低bus带宽
  • write back回写/回填 cache:dirty cache先失效,内存后更新

图片.png

图片.png

MESI通过2bit表示4个cache line状态。下面的状态是缓存行的状态。

  • Modified。cache被更新,与内存数据不一致。只有一个cache有此更新后的数据拷贝。其他CPU的cache都是dirty。
  • Exclusive。cache数据与内存数据一致,只有一个cache缓存了此数据拷贝。
  • Shared。cache数据与内存数数一致。其他cache可能也缓存了此数据拷贝。
  • Invalid。cache数据无效。

图片.png

  • 缓存行根据内存访问事件更新状态
  • 访问事件:
    • 缓存访问事件
    • 总线事件
  • 缓存行只会更新地址匹配的状态。

缓存:

  • read hit
  • read miss
  • write hit
  • write miss

read hit

图片.png

  • 该缓存行必须是MES状态之一。要么是Modified状态、要么是Exclusive、要么是Shared。
  • 本地cache必须是正确的。(比如,M状态下,必须本地cache已经更新完)
  • 直接返回
  • 状态不发生改变

read miss

图片.png

  • cache中不存在拷贝
    • 该CPU请求总线访问主存
    • 将数据从主存读到本地cache,标记为E状态(Exclusive)
  • 有一个cache存在E状态(Exclusive)备份
    • 该CPU请求总线访问主存
    • 嗅探cache将备份数据写到总线
    • 该CPU发起的主存访问被放弃
    • 该CPU缓存数据
    • 将这两个CPU的cache line都设置为状态S(shared)

图片.png

  • 其他的cache有S状态的拷贝
    • 该CPU请求总线访问主存
    • 其他cache仲裁出一个cache将数据拷贝写到总线
    • 该CPU发起的主存访问被放弃
    • 该CPU缓存数据
    • 该CPU备份设置为S状态
    • 其他CPU备份保持为S状态

图片.png

  • 一个cache有M状态的拷贝
    • 该CPU请求总线访问主存
    • 有M状态拷贝的CPU cache嗅探到后,将数据拷贝写到总线
    • 该CPU发起的主存访问被放弃
    • 该CPU缓存数据
    • 该CPU备份设置为S状态
    • 有M状态拷贝的CPU cache将数据写回到主存
    • 有M状态拷贝的CPU cache将缓存行状态从M置为S

write hit

图片.png

图片.png

该CPU缓存行状态必须是MES之一。下面逐个分析每个状态的情况:

  • M

    • M状态下的缓存行其实是排他的(即其他CPU缓存行肯定不存在该数据),其实已经是"dirty"状态了。
    • 更新该CPU的缓存行值
    • 状态无需变更
  • E

    • 更新该CPU的缓存行值
    • 更新该CPU缓存行状态,从E置为M
  • S

    • 处理器在总线广播无效信号
    • 其他CPU嗅探到信号后,将自己的S状态更新为I状态
    • 更新该CPU的缓存行值
    • 更新该CPU缓存行状态,从S置为M

write miss

图片.png

图片.png

图片.png

图片.png

该过程取决于该数据在其他处理器的拷贝状态。

  • 其他CPU cache不存在该数据拷贝
    • 从内存读取到本地cache
    • 更新数据
    • 设置该缓存行状态为M
  • 其他CPU cache存在拷贝,要么其中一个CPU存在E状态的,要么多个CPU存在S状态的
    • 从内存(难道不是其他cache嗅探到后,直接把数据放到总线上?)读取数据到本地cache。此时总线事务被标记为RWITM(read with intent to modify)带着修改的意图去读
    • 其他处理器嗅探到RWITM信号,设置各自状态为I
    • 该CPU更新缓存,设置状态为M
  • 其他CPU cache存在拷贝,但是状态为M
    • 该CPU向总线发送RWITM请求
    • 存在该数据拷贝的CPU嗅探到信号后
      • 阻塞RWITM请求
      • 获得总线控制权
      • 将修改数据写入到内存
      • 将自己的状态置为I
    • 该CPU向总线再次发送RWITW请求
    • 当前应该是:其他处理器不存在该数据拷贝
      • 从内存读取数据到本地
      • 更新数据
      • 设置该缓存行状态为M

MESI状态机

图片.png

图片.png

原文

Cache coherence in shared-memory architectures