## 1 Introduction 现有的DSM相比于单机系统,拓展性差且速度大幅下降,主要源于需要密集的同步操作来保证内存一致性

过往的DSM采用以下方法实现内存一致性:对于要访问的每个数据块,该块要么位于具有潜在读写访问权限的单个节点上,要么跨多个节点复制,每个节点都具有读访问权限仅有的。
在服务器尝试访问块之前,DSM 系统会检查该块的状态,使所有其他服务器上该块的副本无效,然后将该块传输到请求服务器。
此同步过程需要多次网络往返。即使使用 RDMA,与单个本地访问相比,所产生的延迟仍然要高出几个数量级,因此,有效减少同步次数对于最大限度地减少 DSM 开销并使其适合实际部署至关重要。

最小化同步开销的实用策略包括实施高级协议以保证每个服务器的独占访问。例如,Apache Spark [91] 利用称为弹性分布式数据集 (RDD) 的不可变数据结构进行分布式访问。然而,RDD 只促进粗粒度的分布式访问,限制每个服务器只能访问 RDD 的不同分区。虽然增加访问粒度可以提高性能,但代价是通用性降低——Spark 是为批量数据的批量处理而定制的,无法支持需要对象级访问的分布式应用程序

这里可以用作GIM的优势:真正的共享内存来保证一致性

Insight:我们的主要观察结果是,现有 DSM 系统中的同步开销主要是忽略程序语义信息而引入的。例如,许多现实世界的并发程序都是采用单写多读(SWMR)规则来设计的,以确保并发操作期间的正确性。这样可以消除在访问远程数据块前检查其状态的需要,从而显著提高了性能。现在的问题是如何合理的公开这些语义。

编程语言中的所有权可以和SWMR范式结合
Rust 的所有权类型本质上支持任何已编译 Rust 程序中的 SWMR 属性。所有权类型背后的基本概念是确保每个值在整个执行过程中都有一个唯一的变量作为其所有者。虽然允许对一个值进行多个引用,但只有所有者和可变引用才能修改该值。此外,仅允许使用这些引用之一来修改任何给定点的值。

在DRUST中,写操作无需在其他机器上的副本失效,读操作可以有效的复制到每个请求机器,这得益于编译器提供的并发写入保证。

DRust 自动将单机 Rust 程序转换为基于 DSM 的分布式版本,无需重写代码。

DRust 基于分区全局地址空间PGAS的思想构建了一个跨越多个服务器的全局堆。
每个对象在地址空间中都有一个唯一的全局地址,可用于从任何服务器访问该对象。鉴于服务器可以缓存对象(以加速读取),DRust 在全局堆抽象上精心设计了一个基于所有权的缓存一致性协议,以实现内存一致性和效率

简而言之,我们的一致性协议利用所有权语义来消除显式缓存失效的需要。它允许多个读取器从其主机服务器获取对象的副本并将其缓存,但不允许对全局地址和对象的值进行任何更改。当发生写访问时,它必须首先借用所有权,此时 DRust 将全局堆中的对象移动到发出写操作的服务器上的新地址。对象的地址更改会自动使使用过时地址的缓存副本失效,并触发后续读取器通过从最新地址获取对象来更新缓存。

通过我们的编程抽象,Rust 应用程序可以在单个服务器上启动,并逐渐将其线程生成到其他服务器。在底层,DRust 使用运行时来管理应用程序的分布式物理计算和内存资源。

运行时作为集群中每个节点上的进程运行,它们协同工作以进行跨服务器内存分配和线程调度。运行时优先考虑当前服务器进行对象分配和线程创建,但它会在内存压力下将资源分配请求调度到另一台服务器

3 Motivation

High Synchronization Overheads for Coherence
GAM上实验一个应用,对比单机16核和8机2核,性能降低了2.4倍
这种减速主要源于其复杂的一致性协议。 GAM 运行基于目录的协议,为每个 DSM 缓存块分配一个主节点。在每次对象读/写时,主节点都会跟踪其缓存块的状态并更新状态更改的所有缓存副本,从而产生大量的计算和网络开销。

4.1 DRust Programming Abstraction

如图 3 所示,DRust 在所有服务器上维护相同的地址空间布局。它将分布式内存作为一致的共享堆公开给应用程序。采用分区全局地址空间(PGAS)[21]的思想,它对堆空间进行分区并为每个服务器分配唯一的地址范围。相反,堆栈对于每个线程来说是私有的。但是,DRust 会对齐每个服务器上的堆栈空间并填充堆栈以避免重叠。这简化了服务器之间的线程迁移,因为它允许线程在移动时保持其私有堆栈地址不变。
image.png

缓存一致性
为了提高效率,DRust 对新创建的线程采用引用调用模型。创建线程后,DRust 运行时仅将对象的引用或 Box 指针传递给新创建的线程。取消引用后,对象将被获取到执行线程的服务器。
当在服务器上发出对象的读取访问时,我们的运行时只需从其托管服务器获取该对象的副本并将其放入本地缓存中。因此,同一对象的多个副本可能存在于不同的服务器上。这允许多个服务器同时从各自的缓存副本中读取对象。

获取对象的副本进行读取不会更改对象在全局空间中的地址。当对对象进行写访问时,发出写操作的服务器必须首先通过可变借用获得该对象的写访问权限。我们对可变借用的重新实现(稍后讨论)将全局堆中的对象移动到属于该服务器的新地址。这样做时,该对象在其他服务器上的缓存副本会自动失效,而无需发送显式失效消息.在识别所有者的地址更改后,每个不可变借用都会指示服务器从新地址获取对象的新版本,而不是依赖于缓存中的过时副本。

然而,这效率不高,因为每次本地写入都需要将对象移动到新地址。为了解决这种低效率问题,DRust 采用了指针着色技术,其灵感来自许多并发垃圾收集器的设计

指针布局。为了支持该协议,每个指针不仅必须记住对象的全局地址,还必须记住服务器本地缓存中的缓存副本的地址(以避免冗余的远程获取)。因此,我们修改 Rust 的指针结构,如图 4 所示。DRust 在内部扩展了每个 Rust Box 指针和引用,并添加了一个额外的 64 位字段,该字段在读写访问方面的使用方式不同。在高层,该字段记录缓存副本的地址,以实现更快的读取访问;对于写访问,该字段记录对象所有者的地址,用于写后同步。此外,DRust 保留全局地址字段中的最高 16 位作为“颜色”位。这些位记录了指针的版本号,对于DRust高效处理本地写入起着至关重要的作用。接下来,我们讨论DRust如何重新实现Rust的所有权操作来实现分布式一致性协议。为了便于演示,本小节重点介绍该协议的简化版本。完整的一致性协议及其内存一致性证明可在[53]中找到。

在 8 节点集群上评估了我们的系统,其中每个节点均配备双 Intel Xeon E5-2640 v3 处理器(16 核)、128GB RAM 和 40 Gbps Mellanox ConnectX-3 InfiniBand 网络适配器,通过 Mellanox 连接100 Gbps InfiniBand 交换机。所有服务器都运行带有内核 5.14 的 Ubuntu 18.04。

  • 数据分析DataFrame
  • SocialNet 微服务
  • gemm
  • kv存储

9 Conclusion

本文提出了DRust,一个基于所有权模型的实用DSM 系统。它通过语言语义指导的轻量级一致性协议自动将单机 Rust 程序转换为分布式版本。 DRust 显着优于现有最先进的 DSM 系统,证明语言引导的 DSM 可以同时实现强大的记忆一致性、透明度和效率。