数据中心机架级内存解耦架构的设计与评估

摘要

内存解耦被视为解决数据中心内存低效利用问题的强大替代方案。解耦内存具备适应数据中心应用程序(如数据分析、大数据等)内存需求的动态变化能力,这些应用程序需要进行内存内处理。然而,由于互连速度的限制,这些系统可能面临着高远程内存访问延迟的挑战。

在本文中,我们探讨了一种机架级解耦内存架构,并深入讨论了各种设计方面的问题。我们设计了一个基于追踪的模拟器,结合了事件驱动的互连和周期准确的内存模拟器,以评估机架级解耦内存系统的性能。我们的研究表明,远程内存访问延迟的问题不仅与互连速度相关,还与远程内存队列中的争用有关。为了降低延迟,我们引入了一种内存分配策略,与传统策略相比表现出色。我们使用多种不同内存访问模式的基准进行了实验,研究结果显示,我们在机架级内存解耦和平均内存访问延迟方面取得了令人鼓舞的成果。

I. 引言

随着高端服务器级多处理器(例如Xeon Phi和AMD的EPYC)的出现,服务器的计算能力得到了显著提升,可以同时运行多个应用程序。然而,在高性能计算(HPC)设施和云数据中心中,典型的工作负载,如大数据分析和机器学习应用程序,由于内存低效利用和内存容量壁垒[1],导致服务器内存不足的问题愈发凸显。由于对板载内存的不合理使用,内存碎片化成为每个服务器节点内的小片段,从而增加了总体拥有成本[2]。内存的解耦技术为内存管理提供了一种模块化方法,可以以更精细的方式进行管理,而不需要将内存安装在与处理器相同的主板上。它允许内存的独立升级,并延长了数据中心硬件刷新周期[3]。

在本文中,我们研究了一种机架级系统,其中部分内存被解耦,每个计算节点具有一些本地内存以满足主要需求,而大多数应用程序的内存需求则由远程内存满足。远程内存以多个远程内存池的形式在同一机架内进行管理,并根据计算节点的需求进行动态分配。

内存的解耦引入了多个设计挑战。首先,远程内存的位置应合理,以确保多个计算节点可以同时访问远程内存而无明显拥塞。其次,需要如何公开远程内存地址空间,以避免系统级瓶颈并降低额外开销。另一个要求是需要一个集中式内存管理器来负责远程内存的分配,同时需要平衡内存池的负载。不同类型的远程内存访问需要不同的互连设计和协议支持。基于缓存的访问需要内存绑定的支持以实现更快的访问速度[4],[5],而以较大块方式访问远程内存则需要支持远程直接内存访问(RDMA)[6]。我们提出了一个两级远程内存分配机制,一个在计算节点级别,另一个在全局内存管理器级别。研究表明,不同的内存分配方法会对基于内存池的远程内存性能产生影响。

本文的主要贡献如下:

  • 我们探讨了机架级内存解耦的设计,并深入讨论了设计空间。
  • 我们确定了影响远程内存访问延迟的主要因素,并提出了经济有效的内存分配策略,以实现负载平衡以减少尾延迟。
  • 我们评估了所提出的内存分配策略在不同工作负载下的性能,以展示内存解耦的整体影响。

II. 相关工作与动机

早期的设计曾针对传统服务器节点提出机架级内存解耦的方法[7]–[9]。例如,Infiniswap [10] 和 FARM [11] 推出了虚拟内存解耦系统的优化方案,利用RDMA技术访问远程内存,并充分利用其他服务器中的闲置内存。Lim等人 [1],[12] 提出了通用的物理内存解耦设计,其中内存刀片通过PCIe总线连接到计算节点。而Scale-out NUMA [13] 提供了一个芯片内硬件模块,为处理器和远程内存之间提供低延迟接口。Venice [4] 和 DEOI [5] 也研究了类似的芯片内模块,用于远程内存访问,具备细粒度和分页访问远程内存的独立通道。最近,硬件行业领袖共同制定了一项名为Gen-Z的协议标准,类似于芯片内内存一致性互连,其中包括交换机和内存池子系统[14]。Komareddy等人提出了一种面向内存池的共享内存方法,为所有计算节点提供了单一的远程地址空间[15]。然而,大多数数据中心应用程序可以满足其CPU需求,只在极少数情况下需要共享内存访问。在这种情况下,多个计算节点很少需要共享访问远程内存。相反,保持单一域内的一致性将有助于减少一致性流量并降低相关成本开销。我们的研究利用了池化内存系统的非一致性使用,以更好地分配远程内存。

此外,早期对分散内存系统的评估通常是在小规模环境下进行的,要么在虚拟化环境中[2],要么在主机操作系统[16]上进行的,其中网络延迟和地址空间分配通常是固定的。

III. 机架级设计

我们的内存解耦方法专注于机架级的远程内存访问,因为超越机架级别将引入更多延迟,这是由于网络延迟引起的。

A. 池化内存管理

计算节点不仅依赖远程内存以满足大部分内存分配需求,还需要支持这些节点对内存的广泛请求,并确保它们在规定时间内完成。远程内存在其内存队列中可能发生争用,这会显著增加尾延迟。因此,需要更小的内存池和更多的通信通道,以实现高整体内存带宽。目前,关于在一个机架内使用多少个内存池尚无共识,因为分散内存设计仍在实验阶段。我们的基本设计涉及将远程内存划分为多个远程池,后续实验将建立计算节点工作负载需求与内存池数量之间的关系。

B. 远程内存组织

远程内存可以对所有计算节点透明,允许节点上的操作系统从任何部分分配内存。然而,所有节点都应该通过全局内存管理器获得一致的视图。然而,由于大量共享内存引起的一致性流量问题,这种方法可能存在可扩展性问题。另一种方法是提供对远程内存的映射访问,其中任何远程内存页面都专属于单个节点。全局内存管理器可以以较大的块(几兆字节)方式保留远程内存,而不会成为瓶颈。在我们的设计中,我们选择了分布式内存访问。

C. 互连需求

尽管快速网络交换机已显著减少网络延迟,但网络开销的一大部分仍来自节点深层协议堆栈、低速I/O总线以及在请求卸载时进行的协议转换。

(a)集成在芯片上的RMAC
(b)利用RMAC进行数据转发

图1.基于RMAC的远程内存访问

如图1(a)所示,芯片内网络接口,如远程内存访问控制器(RMAC),对于将远程内存资源引入数据中心以进行缓存加载/存储是至关重要的。RMAC是一个可寻址的设备,还负责路由缓存未命中请求到适当的内存池所需的簿记机制。过去,芯片内互连已经在使快速远程内存访问成为可能的领域发挥了关键作用[4],[5],[13],[17],[18],这些方法在数据中心应用程序中非常有效。如图1(b)所示,RMAC将属于远程内存的最后一级缓存(LLC)未命中请求进行转发,并在硬件上实现了轻量级网络协议。另一方面,粗粒度的页访问可以通过类似DMA通道的通道在相同接口上实现,该通道与用户或内核空间的守护程序一起工作,用于监视热门远程内存页面并偶尔将它们传送到本地内存。RDMA互连,如RoCE [19] 和 InfiniBand [20],允许单边访问远程内存,并已在现有数据中心中得到广泛应用[21]。

D. 全局内存管理器

全局内存管理器负责管理单个机架内的所有远程内存。当应用程序在本地内存不足时发生页面错误,它会向全局内存管理器发起请求,以从内存池中分配一个内存块。该块将扩展计算节点上的本地内存地址空间。在Linux操作系统中,这一过程可以通过内存热插拔服务在线升级系统内存来实现。一旦初始化,该服务将向操作系统的页分配器提供所需的内存块。为了更细粒度地控制远程内存,内存应以较小的块进行分配。如果块的分配过小,映射表将变得庞大,导致显著的搜索延迟。然而,如果块的分配过大,内存将被低效利用,类似于传统服务器内存的使用方式,这将增加远程内存回收的复杂性,因为需要大规模的数据迁移。全局内存管理器可以托管在ToR(Top-of-Rack)交换机上,并维护包括已分配和可用远程内存块在内的内存表。一旦管理器分配了一个远程内存块,它将块的详细信息发送给请求节点,以便在远程内存访问控制器(RMAC)中添加适当的本地到远程地址映射,以进行地址转换。

IV. 机架级内存分配

在分散内存系统中,内存分配涉及两个关键方面。首先,计算节点上的页面分配策略必须决定何时开始使用远程内存。节点可以选择首先利用本地内存,或者采用备用的本地-远程分配方法,以获取连续的页面。对于第一种选择,节点最初可获得快速本地内存的性能优势,但一旦本地内存用尽,性能会突然下降。然而,这种方式通常不适用于许多应用程序,因为它们倾向于经历启动阶段,并且在此方案下无法充分利用快速的本地内存。另一种选择允许更长时间的更好的平均内存访问延迟,但不会充分利用快速的本地内存。其次,全局内存管理器需要确定一种内存池选择策略来分配内存块。在池化的远程内存系统中,每个内存池连接到机架顶部交换机的其中一个链路。如果没有负载均衡,一些内存池将吸引更多的请求,从而导致交换机缓冲区拥塞,并增加尾延迟的发生。

A. 随机内存池选择

我们首先使用随机内存池选择策略分析了工作负载WL-Mix(在第五节中解释),在这种情况下,全局管理器会根据计算节点操作系统的每个块分配请求(4MB分配大小),随机选择一个内存池,并且页面分配交替在本地和远程内存之间。

(a)平均内存访问延迟
(b)远程内存访问延迟
(c)延迟分布
(d)内存池中的访问分布

图2.随机内存池选择与本地-远程页面交替分配

如图2(a)所示,每个基准测试的平均内存访问延迟都超过了微秒,远远超出了应用程序正常执行的可接受限制。造成这种高延迟的唯一重要因素是远程内存队列中的争用,这是盲目地将随机远程内存池分配给应用程序内存需求的结果。在图2(b)中可以观察到相同的情况,该图仅显示了平均远程内存延迟,不包括网络延迟。我们对所有内存访问进行了探测,发现2%的内存访问(仅远程)延迟为1000纳秒或更长时间,导致了较高的平均延迟(如图2(c)所示)。在图2(d)中,我们展示了每150万个周期内不同内存池的内存访问次数变化。通过计算在该时期内最大和最小内存访问之间的差值来计算变化。较大的变化显示了内存访问在各个内存池之间的不平衡,导致了较高的尾延迟。

B. 智能空闲内存池选择

智能空闲内存池选择策略在两个不同的步骤中执行最佳内存池选择。第一步是从所有可用的内存池中选择一个小的子集,根据最近的内存访问流量。其基本理念是,当前流量较小的内存池最不可能很快遇到争用,因此可以当前选择用于更多的内存分配。第二步是最终选择一个已分配内存最少的子集中的内存池。背后的原因在于要均衡各个内存池之间的内存块分配数量。此外,即使某个内存池当前的流量较小,如果在过去已分配了更多的内存,它仍然可能会突然面临来自先前分配的内存的更多内存请求。因此,选择已分配内存最少的内存池不太可能面临这种突然的访问。为了实施这一策略,我们使用了托管在机架顶部交换机上的全局内存管理器,该管理器跟踪每个远程内存池的总内存访问量。它只需要一小部分32或64字节的计数器。我们使用基于窗口的机制来测量每个池的访问因子(Af),通过在每个窗口开始时测量每个池的内存访问次数,并计算如(1)所示的访问因子。这里,MemAccCount指的是窗口内对内存池的总内存访问次数。最近的窗口具有更大的权重,以反映内存流量的最新状态。较低的Af值表示某个池最近面临较少的内存流量,因此可以选择用于下一个内存块的分配。

智能空闲内存池选择确保了选择一个当前活跃度较低的池,并且在各个内存池之间均匀分配内存块。假设内存池的总数为n,智能空闲策略首先选择一个大小为m的池子集,其中m的计算如下:m = Ceil[log2(n)]。然后,它最终选择已分配内存最少的内存池。

V. 实验方法和结果

我们对应用程序的全部主内存访问进行了模拟,将它们合并以代表在机架内运行的多个节点,并最终用于互连和内存的模拟。一旦准备就绪,任务就是根据引用地址模拟每个节点的主内存访问,这些访问可以是本地的,也可以是远程的。我们使用Intel的PIN [22]平台进行应用程序分析的二进制仪器化。我们的工具基于一个功能模拟TLB和缓存层次结构的Allcache pin-tool进行修改。这个基本工具经过修改以支持多线程跟踪收集,并为TLB/缓存未命中提供了近似时间,同时进行了基于指令级的仪器化。我们以与[23]相同的方式收集LLC未命中数据,将所有核心中的合并缓存未命中的时间戳进行排序以组合跟踪数据。LLC未命中数据最终提供了主内存访问,同时保留了应用程序的多线程性质,其中每个记录都包括LLC未命中的虚拟地址、时间戳、线程ID和读/写访问类型。跟踪中的虚拟地址经过模拟内存管理单元进行翻译,该单元跟踪本地和远程内存中的页面。对于每个页面错误,它会在本地或远程内存中分配一个新页面。我们还模拟了全局内存管理器,以处理来自节点的远程内存分配请求。

互连的模拟是一系列离散事件,其中一个事件对应一个CPU周期。我们使用基于队列的机制来模拟NIC和机架级互连的延迟。为了进行NIC和机架交换机端口的模拟,我们使用了有限大小的队列,这些队列具备反压拥塞控制策略,并在队列满时为等待的请求添加适当的排队延迟。此外,根据线长和链路速度,我们在每个数据包中添加了传播延迟和传输延迟。每个远程内存访问以网络数据包的形式发送,适当添加了打包和解包时间。一个交换机仲裁器从输入端口的虚拟队列中选择就绪的数据包,以避免饥饿和头部阻塞。最后,我们使用DRAMSim2 [24]来模拟主内存,为此我们部署了多个实例,分别用于计算节点的本地内存和内存池中的远程内存。来自多核前端的排序内存访问有助于在代表多线程执行的环境中进行内存模拟。

表I:基准测试

我们选择了四个多线程基准测试,如表I所示。每个基准测试在模拟期间的内存访问总数方面都有很大的变化,代表了数据中心服务器的异构工作负载。在机架规模的实验中,我们使用了混合工作负载WL-Mix,该工作负载部署在64个计算节点和6个内存池上,每个工作负载中包含了16个节点,每个节点具备256MB的本地内存。我们故意将内存池数量保持较少,因为我们的目标是测试内存池在高工作负载情况下的最大带宽限制。

表II:仿真参数

表II总结了用于模拟的所有系统参数。我们在本地优先和交替本地-远程页面分配策略上执行实验,并与轮询和智能空闲池选择一起运行。

(a)轮询池选择
(b)智能空闲池选择
(c)平均远程内存访问延迟

图3.使用本地-优先页面分配的平均内存访问延迟

首先,我们讨论了轮询池选择的本地优先页面分配。如图3(a)所示,该图展示了不同模拟时间点的累积平均内存访问延迟,黑色标记表示本地内存不再可用。尽管与随机池选择相比,结果显示平均访问延迟大幅减少,但仍然很高,特别是对于lbm和fotonik。这是因为这两个基准测试将大多数内存访问发送到远程内存。fft和fmm的平均延迟也不足以维持足够的应用程序速度。另一方面,如图3(b)所示,智能空闲策略改善了平均延迟,改进幅度相当大。尽管在epoch4之后在某种程度上出现一些延迟,但没有一个基准测试在整个过程中都面临严重的远程内存队列争用,尽管如此,智能空闲策略仍然保持了较低的平均延迟。即使使用本地优先分配,延迟对于所有基准测试也只是逐渐增加,这是适当的负载平衡的结果。图3(c)显示了轮询和智能空闲池选择的内存池的累积平均内存访问延迟(不包括网络延迟),这与上述结果完全一致。由于在中间突然爆发了大量内存请求,轮询无法完美地处理这些请求在内存池之间的平衡。然而,通过智能空闲策略,块分配被设计成几乎平均地分配到多个池中,这就是为什么它给出了更好的结果。

(a)轮询池选择
(b)智能空闲池选择
(c)平均远程内存访问延迟

图4.使用本地-远程页面交替分配的平均内存访问延迟

接下来,我们通过交替的本地-远程分配来测量性能,如图4所示。如预期的那样,一旦本地内存用完,所有基准测试的延迟都会逐渐增加,而不会出现远程内存访问的突然激增。令人惊讶的是,轮询和智能空闲策略的表现相对于本地优先策略而言更好。这并没有显示最初没有专有访问快速本地内存的太大影响,尽管lbm和fmm具有较大的内存占用量,它们仍能够获得足够好的平均内存延迟。总的来说,我们看到了相同的趋势,智能空闲策略比轮询更好。但是,这次的延迟差异较小。这些结果表明,交替的本地-远程页面分配与智能空闲池选择相结合,可以优化整体平均内存延迟,如图4(b)所示。

(a)远程内存访问延迟分布
(b)延迟分解

图5.基于访问时间的远程内存访问分布和本地/远程/网络时间的延迟分析

深入分析了所有远程内存访问的完成时间,如图5(a)所示。这里的延迟仅包括内存请求到达远程内存并完成内存访问所需的时间。不同颜色的条形图表示根据其访问延迟完成的内存访问数量。尽管使用随机池选择会导致较高的延迟,但轮询池选择策略将其降低。许多内存请求的延迟超过了500纳秒(黄色、浅蓝色和绿色的条形图)。轮询策略未能充分平衡不同内存池之间的内存流量,从而导致了这些高延迟。智能空闲池选择策略结合了本地-远程交替页面分配,相对于简单的轮询策略,可以更好地减少尾延迟。图表显示,只有很少的访问需要超过500纳秒才能完成。

图5(b)展示了所有内存访问的总体延迟分解。智能空闲策略的网络延迟相对较低,因为内存请求均匀分布在连接内存池的多个链路上。然而,不同策略在各个基准测试中的平均远程内存访问时间存在很大的差异。

VI. 结论与未来工作

在本文中,我们研究了机架规模的内存解耦系统,这些系统提供了更灵活的内存利用方式,但也伴随一些开销。通过我们的实验,我们还研究了远程内存访问延迟。当使用传统池选择策略时,远程内存的内存队列高度争用成为主要问题。我们提出的智能空闲池选择策略通过均匀分配内存流量负载到所有内存池中,以抵消高尾延迟,并提供更平衡的本地和远程内存的平均访问延迟。此外,我们还讨论了一些优化方法,如远程预取或将页面从远程迁移到本地内存,这些方法可以用于掩盖远程内存延迟。内存解耦系统需要从共享的远程内存中策略性地选择页面进行迁移,这将成为我们未来工作的一部分。