缓存一致性和同步
在本章中,我们将讨论缓存一致性协议以应对多缓存不一致问题。
缓存一致性问题
在多处理器系统中,数据不一致可能发生在相邻级别之间或内存层次结构的同一级别内。例如,缓存和主内存可能拥有同一对象的不一致副本。
由于多个处理器并行运行,并且多个缓存可能独立拥有同一内存块的不同副本,这会产生缓存一致性问题。 缓存一致性方案通过为每个缓存的数据块维护统一的状态来帮助避免此问题。
![可写数据共享中的不一致](/parallel_computer_architecture/images/inconsistency_sharing_writable_data.jpg)
假设 X 是共享数据的一个元素,已被两个处理器 P1 和 P2 引用。一开始,X 的三个副本是一致的。如果处理器 P1 使用写通策略将新数据 X1 写入缓存,则相同的副本将立即写入共享内存。在这种情况下,缓存内存和主内存之间会出现不一致。当使用写回策略时,当缓存中修改的数据被替换或失效时,主内存将被更新。
一般来说,不一致问题有三个来源 −
- 可写数据共享
- 进程迁移
- I/O 活动
Snoopy 总线协议
Snoopy 协议通过基于总线的内存系统实现高速缓存和共享内存之间的数据一致性。 写入无效和写入更新策略用于维护缓存一致性。
![块 X 的一致副本](/parallel_computer_architecture/images/consistent_copies_block_x.jpg)
![写入无效操作](/parallel_computer_architecture/images/write_invalidate_operation.jpg)
在这种情况下,我们有三个处理器 P1、P2 和 P3,它们在本地缓存和共享内存中都有数据元素"X"的一致副本(图 a)。处理器 P1 使用写入无效协议将 X1 写入其缓存中。因此,所有其他副本都通过总线失效。它用"I"表示(图 b)。无效块也称为脏,即不应使用它们。写入更新协议通过总线更新所有缓存副本。通过使用写回缓存,内存副本也会更新(图 c)。
![写入更新操作](/parallel_computer_architecture/images/write_update_operation.jpg)
缓存事件和操作
在执行内存访问和无效命令时会发生以下事件和操作 −
读取未命中 − 当处理器想要读取一个块而该块不在缓存中时,就会发生读取未命中。这会启动 总线读取 操作。如果不存在脏副本,则具有一致副本的主存储器会向请求的缓存提供副本。如果远程缓存中存在脏副本,则该缓存将限制主存储器并将副本发送到请求的缓存。在这两种情况下,缓存副本在读取未命中后都会进入有效状态。
写入命中 − 如果副本处于脏或 保留 状态,则在本地完成写入,新状态为脏。如果新状态有效,则将向所有缓存广播写入无效命令,使其副本无效。当共享内存写入时,在第一次写入之后保留结果状态。
写入未命中 −如果处理器无法写入本地高速缓存,则副本必须来自主内存或具有脏块的远程高速缓存。这可以通过发送 read-invalidate 命令来完成,该命令将使所有缓存副本无效。然后本地副本将更新为脏状态。
读取命中 − 读取命中始终在本地高速缓存中执行,不会导致状态转换或使用监听总线进行无效化。
块替换 − 当副本脏时,将通过块替换方法将其写回主内存。但是,当副本处于有效、保留或无效状态时,不会进行替换。
基于目录的协议
通过使用多级网络构建具有数百个处理器的大型多处理器,需要修改 snoopy 缓存协议以适应网络功能。在多级网络中执行广播非常昂贵,一致性命令仅发送给保留块副本的缓存。这就是为网络连接的多处理器开发基于目录的协议的原因。
在基于目录的协议系统中,要共享的数据放置在一个公共目录中,该目录可保持缓存之间的一致性。在这里,目录充当过滤器,处理器请求允许将条目从主存储器加载到其缓存存储器中。如果更改了条目,目录将更新它或使具有该条目的其他缓存无效。
硬件同步机制
同步是一种特殊的通信形式,其中不是数据控制,而是在驻留在相同或不同处理器中的通信进程之间交换信息。
多处理器系统使用硬件机制来实现低级同步操作。大多数多处理器都具有硬件机制来实施原子操作(例如内存读取、写入或读取-修改-写入操作)以实现一些同步原语。除了原子内存操作之外,一些处理器间中断也用于同步目的。
共享内存机器中的缓存一致性
当处理器包含本地缓存内存时,维护缓存一致性是多处理器系统中的一个问题。在这个系统中,不同缓存之间很容易出现数据不一致的情况。
主要关注的领域是 −
- 可写数据共享
- 进程迁移
- I/O 活动
可写数据共享
当两个处理器(P1 和 P2)的本地缓存中具有相同的数据元素 (X) 并且一个进程 (P1) 写入数据元素 (X) 时,由于缓存是 P1 的直写本地缓存,因此主内存也会更新。现在,当 P2 尝试读取数据元素 (X) 时,它找不到 X,因为 P2 缓存中的数据元素已过时。
![可写数据共享](/parallel_computer_architecture/images/sharing_of_writable_data.jpg)
进程迁移
在第一阶段,P1 的缓存有数据元素 X,而 P2 没有任何数据。 P2 上的进程首先在 X 上写入,然后迁移到 P1。现在,该进程开始读取数据元素 X,但由于处理器 P1 具有过时的数据,因此该进程无法读取它。因此,P1 上的进程写入数据元素 X,然后迁移到 P2。迁移后,P2 上的进程开始读取数据元素 X,但它在主内存中发现 X 的过时版本。
![进程迁移](/parallel_computer_architecture/images/process_migration.jpg)
I/O 活动
如图所示,在双处理器多处理器架构中,I/O 设备被添加到总线上。一开始,两个缓存都包含数据元素 X。当 I/O 设备收到新元素 X 时,它会将新元素直接存储在主内存中。现在,当 P1 或 P2(假设 P1)尝试读取元素 X 时,它会获得一个过时的副本。因此,P1 写入元素 X。现在,如果 I/O 设备尝试传输 X,它会得到一份过时的副本。
![输入输出活动](/parallel_computer_architecture/images/input_output_activity.jpg)
统一内存访问 (UMA)
统一内存访问 (UMA) 架构意味着共享内存对于系统中的所有处理器都是相同的。UMA 机器的流行类别通常用于(文件)服务器,即所谓的对称多处理器 (SMP)。在 SMP 中,所有系统资源(如内存、磁盘、其他 I/O 设备等)都可以通过处理器以统一的方式访问。
非统一内存访问 (NUMA)
在 NUMA 架构中,有多个具有内部间接/共享网络的 SMP 集群,它们通过可扩展的消息传递网络连接在一起。因此,NUMA 架构是逻辑上共享的物理分布式内存架构。
在 NUMA 机器中,处理器的缓存控制器确定内存引用是本地的还是远程的。为了减少远程内存访问的次数,NUMA 架构通常应用可以缓存远程数据的缓存处理器。但是当涉及缓存时,需要保持缓存一致性。因此这些系统也称为 CC-NUMA(缓存一致性 NUMA)。
仅缓存内存架构 (COMA)
COMA 机器与 NUMA 机器类似,唯一的区别是 COMA 机器的主内存充当直接映射或组相联缓存。数据块根据其地址散列到 DRAM 缓存中的某个位置。远程获取的数据实际上存储在本地主内存中。此外,数据块没有固定的主位置,它们可以在整个系统中自由移动。
COMA 架构大多具有分层消息传递网络。这种树中的交换机包含一个目录,其中数据元素作为其子树。由于数据没有主位置,因此必须明确搜索它。这意味着远程访问需要遍历树中的交换机以在其目录中搜索所需的数据。因此,如果网络中的交换机从其子树接收到对同一数据的多个请求,它会将它们组合成一个请求,然后发送给交换机的父级。当请求的数据返回时,交换机会将其多个副本发送到其子树。
COMA 与 CC-NUMA
以下是 COMA 和 CC-NUMA 之间的区别。
COMA 往往比 CC-NUMA 更灵活,因为 COMA 透明地支持数据的迁移和复制,而不需要操作系统。
COMA 机器的构建成本高昂且复杂,因为它们需要非标准内存管理硬件,并且一致性协议更难实现。
COMA 中的远程访问通常比 CC-NUMA 中的访问慢,因为需要遍历树形网络才能找到数据。