多处理机的Cache一致性问题及其解决方案

1 多处理机体系结构

一种很朴素的提高计算机解决问题的性能的方法是,把多个小的计算机连接起来、并行执行相对独立的任务、必要时互相做到通信,就可以制造出一台功能强大、性能较高的计算机,这也是多处理机技术的基本思想。

在这,我们将讨论的多处理机局限于

  • 处理机的协调与使用由单一的处理器系统来控制。
  • 多处理机通过共享地址空间来共享存储器。
  • 各个处理机有自己的 Cache

在逻辑上,多处理机共享地址空间。而在物理上,可以采取两种方式布置主存储器,可以采取集中式和分布式。如下图:

对于图一的集中式结构,通常称其为集中式共享存储器体系结构,这种体系结构还有的一个特点是,所有的处理器访问存储器的延迟都是一致的,有时也被称为UMA结构(Uniform Memory Access)。

对于图二的集中式结构,通常称其为分布式共享存储器体系结构,这种体系结构采用了分布式处理器,各处理器间通过互联网络进行数据的传送,有时也被称为NUMA结构(Non-Uniform Memory Access)。

而无论是哪一种结构,都可能会出现数据共享的问题,即两个不同处理机的 Cache 存放了缓存了同一个主存单元的块,即共享数据,这种情况就可能会导致 Cache 一致性问题的出现。


2 Cache一致性问题

通过下图,我们能理解什么是 Cache 一致性问题。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l55pCTTO-1611658082232)(D:\computer_arch\multi_processor\一致性问题.png)]

具体的过程描述如下:

  • 初始时,CPU A Cache 以及CPU B Cache 中无缓存内容,而主存中的X单元存储的内容为1。
  • 在1时间时,CPU A 读取 X 单元,由于CPU A Cache 中无缓存内容,因此将主存中的数据读入CPU A Cache 中。
  • 在2时间时,CPU B 读取 X 单元,由于CPU B Cache 中无缓存内容,因此将主存中的数据读入CPU B Cache 中。
  • 在3时间时,CPU AX 单元写入0,假设写策略为写直达法,由于主存是共享的,CPU A 将更新其 Cache 的内容为0,且将主存的 X 单元的内容更新为0。
  • 但是 CPU B Cache 中缓存的 X 单元的值仍为旧值,这就导致不一致的情况出现了。

为实现 Cache 的一致性,针对两种体系结构,可以采用两种不同的方法保证 Cache 的一致性。


3 监听一致性协议

针对第一种体系结构,即集中式共享存储器体系结构,来说明这种协议,并且假设Cache 的写命中策略是写回法

所谓监听,就是每个 CPU 都有一个Cache控制器,随时对通过总线中的数据进行判断,判断自己这是否有总线上请求的数据块。

我们讨论两种保持一致性的方式:写作废方式、写更新方式。

3.1 写作废方式

这种方式的基本思想是,当某个 CPU 出现写请求时,将其它的副本直接作废。其详细过程如下,

为了更好地讨论协议,我们将每个CPUCache 的每个块都归结为下述的三种状态:

  • 未缓冲(U):所有的 Cache 中都无此块。
  • 专有态(E):即该块仅仅在该Cache 中有副本,且该块的内容与主存中的不一致。
  • 共享态(S):即该块在一个或多个 Cache 中有副本,且内容与主存中一致。
3.1.1 具体流程
  • 假设 CPU 1 有一个读请求,
    • 若命中,则 Cache 1 直接将值返回给 CPU 1
    • 若未命中,就把读失效信号、以及相应地址放到总线上,其他的的 CPU 一直监听着总线,CPU 1 进行读取主存的操作,
      • 若该地址不能在其他 CPUCache 中被匹配,则结果就是 CPU 1 能正常从主存中读取出数据,且将该块设置为共享态
      • 若该地址在 CPU 2 中被匹配上,且该块在 CPU 2Cache 中的状态是共享态,那么CPU 2 将不会采取任何操作。
      • 若该地址在 CPU 2 中被匹配上,且该块在 CPU 2Cache 中的状态是专有态,那么CPU 2 将向 CPU 1 提供该块,并停止 CPU 1 访问主存的操作。同时,该块将被写回至主存,CPU 1 Cache 以及 CPU 2 Cache 中该块的状态修改为 共享态
  • 假设 CPU 1 有一个写请求,
    • 若写命中,
      • 若该块在CPU 1 Cache 中的状态是共享态,那么 CPU 1 将该块状态改为专有态,且向总线发送写作废信号,使得别的 CPU 将其Cache 中相应的共享块(若存在)设置为无效
      • 若该块在CPU 1 Cache 中的状态是专有态,那么 CPU 1 进行正常的写数据的操作,即将新数据写入该块。
    • 若写缺失,
      • 那么 CPU 1 将该块状态改为专有态,并且正常写入数据,且向总线发送写作废信号,使得别的 CPU 将其Cache 中相应的块(若存在)设置为无效
3.1.2 状态转换图

其状态转换图如下,

3.2 写更新方式

这种方式的思想是,当某个 CPU 出现写请求时,将其它的副本一并更新。

具体说来,就是当一个 CPU 写某数据时,若该块是共享块,通过广播使其他所有 Cache 中有对应副本的块都一并更新。

这种方式很需要总线和存储器的带宽,因为要经常性地广播修改的数据,这使得这种方法被采用地越来越少。


4 目录一致性协议

目录是一种数据结构,记录了 Cache 块的一些状态:

  • Cache 块的访问状态,未缓冲共享态专有态
  • Cache 块的位向量,用于记录该 Cache 块的共享情况,即位向量的每一位代表一个处理器(CPU),若其为 1 ,则表明在该位置的 CPU 有该 Cache 块的副本。

同样地,目录一致性协议也有两种实现方式,即写作废方法、写更新方法,在这里,我们同样假设 Cache 的写策略是写回法

此时,Cache 每个块的状态转换模式和监听一致性协议是一样的

基于目录的一致性协议要避免不必要的性能损失,比如避免广播,而是根据位向量,找到对应的 CPU 向其发送信息。

总结一下目录一致性协议的基本点:

  • 每个 CPU 节点增加了目录存储,用于存放目录
  • 存储的的每一块在目录中都有对应的一项。
  • 每一个目录项的组成成分是:访问状态、位向量。
  • 状态描述该目录项对应的存储块的访问状态:未缓冲共享态专有态
  • 位向量的每一位对应于一个 CPUCache,用于指出该 CPUCache 有无该块的缓存。
  • 当处理器对某一块进行写操作时,需要根据位向量,**”通知“**对应的 CPU 进行作废或更新操作。

基于目录的一致性协议配合分布式共享存储器体系结构,能很好地支持系统的可扩展性,然而,这种多处理机的实现模式,需要带宽较大的网络来实现,普通的以太网是远远达不到带宽要求的。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐