Skip to the content.

《Shared Memory Consistency Models: A Tutorial》中文总结

原文:Sarita V. Adve, Kourosh Gharachorloo, Shared Memory Consistency Models: A Tutorial, WRL Research Report 95/7, September 1995.

1. 背景与动机

随着支持共享内存抽象的多处理器系统在技术与商业计算中得到广泛应用,程序员迫切需要一种精确描述“内存如何表现”的规约,即内存一致性模型。最直观的模型是顺序一致性(Sequential Consistency, SC),它要求所有内存操作看起来按某种全局顺序一次执行一个,且每个处理器的操作保持其程序顺序。顺序一致性能让程序员像编写单线程程序一样思考并行程序,但它也禁止了许多单处理器中常见的硬件与编译器优化(写缓冲、非阻塞读、指令重排、寄存器分配等),从而严重制约多处理器性能。

为缓解这一问题,学术界和工业界提出了多种宽松内存一致性模型(Relaxed Memory Consistency Models)。然而,不同模型的术语、规约方法和允许优化各不相同,给理解和移植带来困难。本文旨在用统一、简单的术语,向计算机专业人员介绍顺序一致性与主要宽松模型。

2. 单处理器内存语义

单处理器高级语言通常提供简单的顺序语义:程序员可以假设内存操作按程序顺序一次一个执行,读操作返回同一位置之前最后一次写入的值。实际上,只要维护数据依赖控制依赖,编译器和硬件就可以自由重排针对不同位置的操作,从而启用大量优化而不破坏程序语义。多处理器则需要更复杂的规约。

3. 顺序一致性

Lamport 对顺序一致性的形式化定义是:任何执行的结果都等同于所有处理器的操作按某种顺序依次执行的结果,并且每个单独处理器的操作在此序列中按其程序顺序出现。

顺序一致性包含两个核心方面:

  1. 程序顺序:维护单个处理器操作之间的顺序。
  2. 原子性/全局串行化:维护所有处理器操作之间的单一全局顺序,使每个操作看起来瞬时完成。

图 4 用 Dekker 算法示例说明程序顺序的重要性,用多处理器共享变量示例说明原子性的重要性。

4. 实现顺序一致性的挑战

实现顺序一致性需要约束多种硬件与编译器优化。

4.1 无缓存架构下的典型问题

4.2 带缓存架构下的额外问题

4.3 编译器

编译器重排共享内存操作、或把共享变量分配到寄存器,都可能违反顺序一致性。因此,在顺序一致性下,许多单处理器优化无法直接应用。

5. 宽松内存一致性模型

宽松模型的基本思想是:在不影响程序正确性的前提下,放宽顺序一致性的某些约束,以允许更多优化。模型主要按两个维度分类:

  1. 程序顺序放宽:是否允许重排 写→读、写→写、读→读/写。
  2. 写原子性放宽:是否允许读在写对所有处理器可见前返回该写的值。

5.1 仅放宽 写→读 程序顺序

5.2 进一步放宽 写→写 程序顺序

5.3 放宽所有程序顺序

这些模型为编译器提供了更大的优化空间:在两个同步点或栅栏之间的操作几乎可以像单处理器程序一样被重排。

6. 以程序员为中心的视角

以系统为中心的规约直接暴露优化细节,增加了编程复杂度。为此,文章介绍了以程序员为中心的抽象:程序员只需在程序中标识哪些操作可能参与竞争(即应被视为同步操作),系统据此判断可安全应用哪些优化。只要程序员提供的信息正确,系统就能在保持“顺序一致性假象”的前提下进行优化。

这种信息可以通过高级语言构造(如 doall、同步库)、变量类型声明或地址范围属性传达给编译器和硬件;在缺乏直接硬件支持时,编译器可将其转换为显式栅栏指令。

7. 结论

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。