Paper Reading: Can Far Memory Improve Job Throughput? (Fastswap)
Can Far Memory Improve Job Throughput?
memory disaggregation 内存解耦的论文,稍微看看
Abstract
随着内存需求的增加和内存技术进步的放缓,大型计算集群中主内存的可用性越来越成为瓶颈。
种解决方案是内存解耦,即作业可以远程访问其他服务器上的内存,或称为远端内存
本文首先介绍了更快的交换机制和一个支持远端内存的集群调度器,使其能够在机架 rack 规模上支持远端内存。
memory-intensive workloads
机架规模是什么,一个架子上的一堆机器?
Introduction
内存密集型工作负载(如机器学习应用和键值存储)的日益流行,
虽然远端内存并不减少运行单个作业所需的内存总量,也不使内存更便宜或更密集,但它确实意味着作业不必局限于本地内存,而是可以利用集群中其他位置的内存。这绕过了“内存容量墙”[48],并增加了内存跨作业共享的效率。
google 利用 zswap 来实现远端内存,和这里提到的有什么区别?他们的 bigtable 表现好像也一般,没有降低太多的成本
没有给其他的性能参数,本篇倒是很在意吞吐量,不知道是不是动态负载或者突发负载
使远端内存实用化面临两大障碍。
- 第一个障碍在于如何设计访问远端内存所需的交换机制,因为现有系统通过 RDMA 进行交换时,由于 head-of-line blocking, and to handling interrupts and page reclamation on the critical path of page fault resolution, 导致延迟和吞吐量不佳。我们设计了一个名为
Fastswap
的 Linux 交换系统,该系统通过 RDMA 优化使用远端内存。
头阻塞,HOL blocking 队列头部处理缓慢,RDMA 使用队列管理,容易发生头阻塞
与其他交换系统一样,它对应用程序和开发者都是透明的。此外,它直接与 Linux 控制组[5]交互,允许 Fastswap 强制执行本地内存分配。Fastswap 通过将关键路径上的页面获取引导到单独的队列来防止头阻塞。此外,它通过轮询关键页面操作的完成情况,并将内存回收卸载到专用 CPU,从而减少关键路径上的延迟。因此,Fastswap 实现了<5 微秒的远程页面访问延迟,使应用程序能够以 10 Gbps 的速度(单线程)和 25 Gbps 的速度(多线程)访问远端内存。Infiniswap[34]是最接近的相关工作,Fastswap 的带宽在单线程时比 Infiniswap 高 1.51 倍,在多线程时高 2.54 倍(禁用备份磁盘时)
critical path 是决定整个任务完成时间的最长路径?比如 page fault, interrupts, reclaim?
第二个障碍在于如何决定将每个作业的内存需求在本地内存和远端内存之间进行分配。
使用远端内存在某种程度上是一个装箱问题:如何在每个服务器上给定数量的本地内存和大量远端内存的情况下,以最快的速度处理工作负载,并且每个作业必须分配满足其需求总量的内存(本地和远程)?
为什么不是肯定优先本地呢?
为此,我们设计了一个远端内存感知的集群调度器,利用远端内存来提高作业吞吐量。当一个新作业到达时,调度器可以将作业放置在一个初始可用本地内存不足以处理所有分配给它的作业的服务器上。然后,我们的调度器减少该服务器上一些现有作业使用的本地内存,并使用远端内存确保所有作业都能访问足够的总内存。这种策略是否有益尚不明确,因为使用远端内存不可避免地会减慢单个作业的速度(因为访问远端内存比访问本地内存慢得多)。然而,使用远端内存也可以使更多作业在单个服务器上同时运行,尽管速度较慢,这可能会提高整体吞吐量。我们广泛研究了这种权衡,并报告了在何种情况下使用远端内存可以提高整体吞吐量,以及这与仅增加本地内存量的比较。据我们所知,这是对这些问题的首次系统性探索。
一种 trade off 还是无意义?
改进的交换系统 Fastswap 和集群调度器的结合提供了对 cluster-wide far memory 的支持,我们称之为 CFM,但我们使用了一个集群模拟器
We find that far memory is not a panacea
系统设计没有银弹
如果内存需求远大于可用内存,那么通过增加每个服务器的本地内存而不是将等量的内存添加到共享的远端内存服务器上,可以获得更好的性能。然而,我们发现远端内存在单个机架的两个关键场景中提供了显著的好处:(1)如果工作负载是内存密集型的(即内存可用性而不是核心可用性是瓶颈),将计算节点转换为远端内存服务器可以导致(在我们研究的情况下)与原始机架相比大约 10% 的吞吐量提升,尽管两种机架配置的内存总量相同。(2)如果操作员希望适度增加机架的内存容量,向内存服务器添加内存允许更细粒度的增加,这仍然会导致显著的性能提升,而升级每个服务器的本地内存只能以更大的(因此更昂贵的)增量进行(正如我们在下一节中讨论的那样)。
Context
Memory Provisioning
重要的是要记住,本地内存只能以粗粒度进行配置。
啥意思?跟 DIMM 插槽有关?
Deployment Scenarios
我们主要不是考虑 green-field deployments 但我们的主要关注点是逐步升级现有部署。他们现有的数据中心往往已经填满了所有 DIMM 插槽。这在经济上是合理的,因为每单位内存的成本随着 DIMM 容量的增加而增加,因此配置给定数量的内存的最便宜方式是使用所有可用的 DIMM 插槽。
green-field deployments 绿场部署,是从头开始,全新的部署
虽然远端内存有可能提高集群吞吐量,但这会以单个作业运行时间变慢为代价。因此,我们认为远端内存最适合那些主要指标是作业吞吐量的应用,而不是面向客户或对延迟敏感的应用;这是本文的重点。
CFM Overview
CFM 的目标是通过利用专用内存服务器上的远端内存来提高集群的端到端作业吞吐量。
尽管之前的研究已经探索了启用远端内存的机制,并展示了单个作业在交换时的性能优势(例如,[34]),但据我们所知,没有先前的研究在机架规模上展示了远端内存的性能改进。我们专注于改进端到端完成时间,即完成执行作业列表所需的时间。在高层次上,CFM 的方法(§3.1)与先前的工作相似,但 CFM 克服了几个关键挑战(§3.2),这些挑战使得今天难以从远端内存中获得集群规模的收益。
这里提到单个作业性能提高的论文是
Juncheng Gu, Youngmoon Lee, Yiwen Zhang, Mosharaf Chowdhury, and Kang G. Shin. 2017. Efficient Memory Disaggregation with INFINISWAP. In Symposium on Networked Systems Design and Implementation (NSDI’17). 649–667.
Approach
在 CFM 中,应用程序通过 RDMA 交换来利用远端内存。CFM 使用 Linux 控制组来强制执行内存分配。
Swapping: 应用程序可以通过两种广泛的方式利用远端内存:透明地(无需应用程序修改),或通过显式且可能是自定义的 API。 相反,类似于 Infiniswap [34],CFM 通过交换实现远端内存,这是一种现有的机制,将虚拟内存扩展到物理可用内存之外。当 CPU 访问物理内存中不存在的页面中的内存地址时,会引发页面故障,页面故障处理程序透明地将页面内容从交换空间获取到本地内存中。传统上,交换空间位于磁盘上,由此产生的毫秒级访问延迟对工作负载引入了大且难以理解的性能开销。然而,交换本身并不意味着毫秒级的延迟,并且随着今天的微秒级网络延迟,通过网络交换到远端内存有可能获得良好的性能。
Cgroups: CFM 使用 Linux 控制组(cgroups)[5]来enforces 执行每个作业的本地内存消耗限制。控制组控制分配给一组进程的物理内存量,CFM 使用交换系统将多余的内存保持在远端内存中。
Control Groups,cgroups
RDMA: CFM 利用 RDMA 进行低延迟访问远程服务器上的内存。CFM 使用 one-sided read and write 操作,这些操作可以在不使用远程 CPU 的情况下访问内存,通常,RDMA 操作提交到本地队列对,然后由本地 RDMA NIC 处理。一旦操作完成,NIC 将完成情况发布到完成队列;完成队列可以配置为在完成到达时引发中断,或保持静默,期望它们将被轮询。传统上,RDMA 绕过远程和本地操作系统,但 RDMA 也提供了一个内核 API 供驱动程序使用;CFM 利用此 API 通过网络交换页面。
什么 API?
Challenges and Contributions
两个主要挑战:快速交换和决定如何在本地和远端内存之间调度作业
Fast Swapping
RDMA 交换设备已经在先前的研究中进行了探索,例如 Infiniswap [34]和 HPBD [47]。然而,这些方法无法维持当今应用程序所需的高性能
- 为了隐藏未来页面故障的 I/O 延迟,操作系统通常通过在每次页面故障时获取多个页面来实现页面预取。不幸的是,在 Linux 中,故障页面——应用程序当前所需的页面——可能位于要预取的对齐页面窗口中的任何位置。因此使用 Linux 默认的预取窗口大小 8,头阻塞可能会延迟故障处理数十微秒。
- 在现有的通过 RDMA 进行交换的系统中,CPU 通过中断通知 RDMA 操作(例如,读取远程页面)已完成。这种中断处理发生在关键路径上——在页面故障处理程序能够返回到应用程序之前——并且可能会增加 10 微秒或更多的页面故障处理时间[13]。
- 在故障页面的内容被读入本地内存后,操作系统通过增加其内存计数器将其计入其控制组。如果控制组内存限制被超过,则需要回收多余的页面。与 Linux 中的系统范围回收不同,控制组中的内存回收总是直接进行的,即在离开页面故障处理程序并返回到应用程序之前。因此,整个回收过程(查找要回收的页面,将它们写入交换设备,并将页面返回内核以供重用)会延迟页面故障解决。
CFM 引入了一个名为 Fastswap(§4)的更快的交换系统,克服了所有这三个挑战,使 CFM 能够实现比现有系统(如 Infiniswap)更低的延迟和更高的远程交换吞吐量(§6.4)。
Cluster Scheduling
许多现有的调度器通过在核心、内存和其他资源之间调度作业来实现集群资源的有效共享。然而,现有调度器不考虑远端内存;也就是说,它们不支持调度内存可以在本地和远端内存之间动态分割的作业,也不指定如何最好地在共享同一机器的多个作业之间分配本地内存。CFM 提出了一种集中的远端内存感知调度器(§5),在将作业分配给机器时考虑远端内存,并决定如何在不同作业之间划分本地内存以优化完成时间。
Fastswap
但我们发现,要实现更高的交换性能,需要对页面故障处理程序、交换系统和控制组内存控制器进行修改。我们通过修改大约 300 行内核代码和为 Linux 4.11 编写了一个新的 1200 行代码的设备驱动程序来实现 Fastswap
提高分页性能具有挑战性。虽然许多系统专注于在毫秒时间尺度上进行改进[35, 46],但我们的系统力求实现微秒尺度的交换。我们在本节中讨论的大多数机制发生在程序执行暂停时。因此,我们节省的每一微秒都是返回给应用程序的计算时间。
?? 他是怎么实现微秒级别的
RDMA Backend
在 Fastswap 中,操作系统使用 RDMA 后端与 RDMA NIC 交互
如图 2 所示,后端用于所有交换操作类型:页面故障、预取和内存回收。尽管之前的研究已经将 RDMA 后端暴露为块设备
block device 是什么?
Queue pairs: 给定队列对中的 RDMA 请求由 NIC 处理单元按顺序处理,如果不同类别的交换操作共享一个队列,关键操作——例如,故障页面的读取和被驱逐页面的写入——将排在不太紧急的预取读取之后。Fastswap 通过为每个 CPU 使用两个 RDMA 队列对来避免这种头阻塞,一个用于关键路径上的操作,一个用于预取。
Frontswap interface: Frontswap 假设其操作是同步完成的[3],即在 Frontswap 操作完成后,执行控制才会返回到交换系统。因此,它没有提供区分关键路径上的操作和非关键操作的机制。因此,Fastswap 增强了 Frontswap 接口,以区分关键和非关键操作,使 RDMA 后端能够将请求引导到适当的队列对。
加队列就完了
Page Fault Handler
Fastswap 通过两种关键方式修改页面故障处理程序。
首先,它指示交换系统以不同的方式处理故障页面和预取页面,如上所述。其次,Fastswap 修改交换系统,首先读取故障页面,然后读取预取窗口内的剩余页面
在发出所有读取操作后,Fastswap 轮询等待故障读取完成。通过首先发出故障读取,我们重叠了为预取读取分配物理页面的延迟和发出预取 RDMA 读取的延迟,与故障页面的 RDMA 读取。图 3 展示了 Fastswap 如何处理页面故障及其相关的预取。
分别处理故障页面和预取页面最小化了错过预取的成本。例如,假设页面故障 1 发生在地址 F1,并有一组相关的预取页面 P1。我们的交换系统将发出 F1 和 P1 的读取操作,并轮询直到 F1 的读取完成。此时,页面故障处理程序将返回到用户空间。然后,假设页面故障 2 发生在地址 F2,其中 F2 < P1(即预取未命中)。Fastswap 可以在不等待 P1 中的任何页面的情况下获取 F2,而之前的系统则需要等待 P1 中的所有页面完成后才能完成 F2 的读取
fastswap 就是把预读的优先级降低了?
Memory Reclaim
我们已经介绍了 Fastswap 交换系统如何将页面从远端内存带入本地内存。现在我们描述 Fastswap 如何回收内存,以确保进程不会使用超过其允许份额的本地内存。Fastswap 通过修改控制组内存控制器,将回收操作从页面故障处理的关键路径上移除。
传统上,在读取故障页面后,内存控制器将页面计入其控制组。然后,控制器检查控制组是否有超过其允许份额的内存。如果有多余的页面,它们会被直接回收,并可能被驱逐到远端内存。直接回收发生在页面故障处理程序的上下文中,因此它会阻止 CPU 返回到用户空间并继续工作负载执行。
Linux 中的内存回收出乎意料地昂贵,当我们的应用程序有 50%的内存位于远端内存时,消耗了 62-85%的内核时间。为了减少这些成本,每当节点使用远端内存时,我们修改的内存控制器将内存回收卸载到专用回收 CPU(图 2);我们称之为卸载回收 offloaded reclaim。卸载内存回收允许导致页面故障的 CPU 在不需要花费时间进行直接回收的情况下返回到用户空间。最近的努力已经使用了类似的方法来卸载冷内存压缩[43]和数据包处理[22, 52]到专用 CPU。
无论内存回收是直接的还是卸载的,在将页面驱逐到远端内存时,我们都会轮询它们的完成情况。只有在页面写入远端内存完成后,页面才能完全回收。
Far Memory-Aware Scheduler
…
后面都省略了,实验也跳过,怪怪的
使用了定义的几个参数,负载 / 集群配置差不多,看远端内存会调用多少,然后做了一个最优化问题,最大 (A - B) / C, A−B is the total local memory-time product saving, C is the total far memory-time product
更想看每个组件的表现而不是这种