GPU Initiated OpenSHMEM: Correct and Eicient Intra-Kernel Networking for dGPUs
作者/机构: Khaled Hamidouche (Advanced Micro Devices, Inc.), Michael LeBeane (Advanced Micro Devices, Inc.)
A1 主要贡献
本文旨在解决当前GPU网络通信中存在的性能瓶颈和编程复杂性问题。
核心问题:
现有的GPU网络通信模型是“以主机为中心、在内核边界进行通信”的模式。这种模式存在两大问题:
1. 性能低下: 每次通信都需要启动和结束GPU内核,而内核启动的开销高达20µs以上,远超现代网络约0.7µs的延迟。这导致网络和GPU资源利用效率低下。
2. 编程复杂: 程序员必须将通信与计算分开考虑,无法在GPU内核代码中直接嵌入网络调用,增加了算法实现的复杂性,降低了开发效率。
现有解决方案及其缺陷:
尽管近期研究探索了在GPU内核内部直接发起网络通信(即“核内网络通信”),但这些方法普遍存在两个共同的缺陷:
1. 高延迟: 在GPU上创建和提交网络命令包(packet)是一个串行内存操作过程,与GPU的单指令多线程(SIMT)执行模式不匹配,导致通信发起延迟比网络本身延迟高出一个数量级。
2. 数据可见性与顺序性问题: GPU采用宽松的内存一致性模型,其产生的数据仅在内核边界才能保证对外部设备(如网卡NIC)可见和有序。为解决此问题,大多数现有工作依赖CPU介入来执行数据一致性操作,但这又将CPU引入了通信的关键路径,削弱了核内网络通信带来的性能优势。部分不依赖CPU的工作则会因违反内存一致性模型而报告间歇性的数据校验错误。
本文的创新点与主要贡献:
为解决上述问题,本文提出了GPU Initiated OpenSHMEM (GIO),一个以GPU为中心的PGAS编程模型和运行时系统,旨在将GPU提升为分布式系统中的“一等公民”。GIO的核心贡献如下:
- 分析并解决内存一致性问题: 深入分析了GPU粗粒度的内存一致性模型与核内网络通信需求之间的语义不匹配问题,并提出了系统级和运行时级的设计来克服这些限制,首次实现了在不引入CPU到关键路径的情况下,保证数据正确性和顺序性的核内网络通信。
- 低延迟的模板化设计: 提出了一种新颖的基于模板的网络包生成方法。该方法将网络包中不变的静态信息在CPU端预先填充为模板,GPU在通信时只需更新少量动态信息(如源/目的地址、大小),极大地减少了GPU发起网络操作的串行开销和延迟。
- GIO编程模型与运行时系统: 设计并实现了一个完整的运行时系统,通过驱动程序扩展和创新的API设计,实现了GPU与NIC的紧密集成,使GPU能够直接、高效地与NIC通信。
- 应用协同设计与验证: 通过在规则应用(Jacobi 2D模板计算)和不规则应用(稀疏三角求解器SpTS)上协同设计内核,验证了GIO的性能优势。实验表明,相比传统的核间网络通信,GIO可将Jacobi性能提升高达40%;相比现有的核内网络通信方案,可将SpTS性能提升高达44%。
A3 背景知识
GPU计算架构
图 1. AMD的Graphics Core Next (GCN [3]) GPU架构,重点关注内存和缓存。
GPU硬件组成。图1展示了一个计算优化型GPU的相关组件。本文使用AMD的特定术语,但大多数概念可直接适用于Nvidia。GPU由多个计算单元(Compute Unit, CU)组成,每个CU又包含一组单指令多数据(SIMD)单元。每个CU连接到一个私有的L1缓存和一个共享的L2缓存,这些缓存通过显式的缓存管理指令进行维护。一组工作项(work-items)以称为“波前”(wavefronts)的束(bundles)被分派到CU上。这些波前进一步被捆绑成“工作组”(workgroups),工作组保证在同一个CU上执行,因此可以利用称为本地数据共享(Local Data Share, LDS)的快速、每个CU独有的暂存器内存。关于GPU内存子系统和一致性模型的更具体细节将在第4.1节讨论。
GPU编程模型。GPU通过编写称为“内核”(kernels)的代码进行编程。在本文中,我们将展示使用异构计算可移植性接口(Heterogeneous-compute Interface for Portability, HIP)【【5,HIP: Heterogeneous-computing Interface for Portability,2018】】语言编写的代码,其语法与CUDA【【25,CUDA Toolkit 9.2,2018】】相似。
RDMA和OpenSHMEM
RDMA技术。远程直接内存访问(Remote Direct Memory Access, RDMA)技术在执行网络操作时绕过目标CPU,并已在许多高性能网络协议中实现【【11,IniniBand Architecture Speciication: Release 1.0.2,2000,IniniBand Trade Association】,【36,The Portals 4.1 Network Programming Interface,2017,Sandia National Laboratories】】。使用InfiniBand的术语,每个端点通过命令队列与NIC交互。发送队列(Send-Queue, SQ)和接收队列(Receive-Queue, RQ)是用户提交命令包给NIC执行的地方,而完成队列(Completion-Queue, CQ)是NIC发布已完成操作状态的地方。这些结构通常统称为队列对(Queue-Pair, QP)。
OpenSHMEM模型。RDMA常用于实现单边通信语义,例如由OpenSHMEM【【6,OpenSHMEM Speciication,2018】】提供的语义。OpenSHMEM是一个分区全局地址空间(Partitioned Global Address Space, PGAS)库规范,定义了许多单边操作,如远程Puts()
和Gets()
,以及同步原语和集合操作。OpenSHMEM中使用的关键数据结构称为对称堆(symmetric heap)。对称堆是一个内存池,其中每个内存分配/释放调用都是跨所有节点的集体操作,因此每个节点在其本地堆中的相同偏移量处都有完全相同的变量。因此,每个节点可以通过使用指向在对称堆上分配的变量的指针来访问另一个节点的堆。在本文中,我们根据OpenSHMEM网络编程标准的语义设计了GIO。
A3 关键Observation/设计原则
本节简要描述了GPU的内存一致性模型以及管理GPU与外部设备(如NIC)交互的主要硬件组件。然后,我们讨论了GPU的内存一致性模型与GPU发起的网络通信愿景之间的不匹配。讨论将主要集中在第2节中描述的AMD GPU架构上。然而,最近的研究在Nvidia GPU上也注意到了类似的观察结果【【1,Oloading Communication Control Logic in GPU Accelerated Applications,2017,CCGrid】,【27,GPUDirect RDMA,2019,Nvidia】】。
GPU内存模型和相关硬件组件
GPU宽松内存模型。GPU在一种宽松内存模型【【10,Heterogeneous-race-free Memory Models,2014,ASPLOS】】下运行,这可能让许多习惯了大多数现代CPU提供的更强保证的程序员感到不熟悉。GPU上的内存访问对应一个“范围”(scope),该范围定义了GPU数据的可见性和顺序性要求的级别(例如,工作组、设备和系统)。为了优化性能,内存事务默认在最受限的范围内操作,除非使用特殊指令来改变内存访问的范围。此外,为了使在更局部范围内产生的数据对更远的范围可见,必须在内存访问流中插入“获取/释放”(acquire/release)标记。释放操作确保所有先前的内存操作都已对请求的范围可见。获取操作确保我们在同步点之后的所有内存操作中看到最新的数据。这些标记根据特定设备的能力和标记的范围被编译成缓存维护操作和硬件栅栏(fences)。
系统范围的可见性。在本文中,由于我们关心数据对其他设备(NIC)的可见性,因此我们关注离GPU最远的范围:系统范围(system-scope)。系统范围涵盖了对GPU外部设备(如NIC或主机CPU)的数据可见性和顺序性要求。不幸的是,当前的GPU没有在内核内管理系统范围的机制。系统范围的获取/释放标记映射到由CPU驱动程序代码和GPU设备固件执行的内核启动(获取)和内核结束(释放)操作。
影响可见性的关键硬件组件。图1描绘了GPU内存子系统,并突出了有助于系统范围可见性和顺序性的主要组件。三个主要组件是:
* GPU L2缓存:GPU在不同的CU之间使用一个共享的末级L2缓存。由于这个L2缓存是所有SIMD引擎共享的,它被用作所有设备范围操作的相干点(coherency point)。L2缓存仅在内核结束时被独占地刷新。在某些架构中,负责管理和调度内核的GPU前端单元——GPU命令处理器(Command Processor, CP),有能力刷新L2缓存。在大多数架构中,无法从GPU着色器代码中刷新L2缓存。
* GPU PCIe路径IP块(PPB):由于GPU通常是PCIe设备,它们需要一个处理和管理所有到GPU内存的PCIe事务的IP块。为了最大化PCIe访问的性能,该块包含一个用于读操作的缓存和一个用于写操作的写合并器(write combiner)。与L2缓存类似,这个读缓存是非相干的,并且仅在内核边界被无效化。
* 无序数据交换结构(DF):为了最大化吞吐量,GPU的宽松内存设计了一个无序的数据交换结构(data fabric)。GPU可以通过显式等待来自DF的确认来排序自己的内存请求,然后再发出后续请求。
GPU内存模型对核内网络通信的影响
当前GPU内存模型的限制。在本节中,我们将讨论GPU发起的网络编程模型对网络的要求以及其与GPU内存一致性模型的不匹配。像GPUDirect RDMA【【19,Mellanox OFED GPUDirect RDMA,2017,Mellanox】】和ROCm RDMA【【4,ROCn RDMA,2017,AMD】】这样的GPU技术通过赋予NIC直接读/写GPU内存的能力,优化了GPU内存和RDMA NIC之间的数据路径。然而,由于第4.1节描述的组件行为所施加的GPU内存一致性限制,网络RDMA操作仅限于内核边界。当内核正在运行时,对GPU内存进行的RDMA操作不能保证数据正确性【【27,GPUDirect RDMA,2019,Nvidia】】。
网络操作与硬件组件的交互。为了分析网络需求及其与当前GPU内存模型的不匹配,我们考虑网络对GPU内存执行的两种操作(从GPU内存读取和向GPU内存写入)以及它们与第4.1节介绍的系统范围硬件组件的交互。
NIC从GPU内存读取数据时的挑战。当NIC执行从GPU内存的PCIe读操作时,请求会被路由到GPU PPB块。如果请求的数据已经在PPB读缓存中(即该地址已被CPU或NIC读取过),NIC将从PPB缓存中读取数据,而不会访问GPU内存。如果GPU在此前的读取之后产生了更新的数据,NIC将获得不一致的数据视图。为避免这种不一致,必须在NIC开始读取数据之前使PPB缓存无效。
L2缓存带来的挑战。如果对于同一次读操作,请求的数据不在PPB缓存中(或该缓存已被无效化),读请求将直接从GPU内存中服务。不幸的是,仍然有可能读到不一致的数据,因为最新的副本可能被卡在GPU的非相干L2缓存中。因此,除了PPB无效化之外,还必须在允许NIC从GPU内存读取数据之前刷新L2缓存。
向GPU内存写入数据时的挑战。对于向GPU内存的写请求,PPB充当一个写合并器(write-combiner, WC),这可能会重新排序写操作。此外,GPU DF本身也有可能重新排序到GPU内存的PCIe写操作。当程序员调用诸如shmem_fence()
之类的操作时,这些重排序点必须被有序化。应用程序编写者通常依赖shmem_fence()
来对批量数据传输和通知目标传输完成的标志进行排序。因此,GIO上的shmem_fence()
操作需要完全刷新PPB写合并器。此外,NIC本身需要发起这个刷新,因为shmem_fence()
通常由请求的发起者调用。
A2 方法细节
图 3. GIO重要数据结构及其在内存中位置的图示。
本节将详细讨论GIO用于允许GPU直接与NIC交互而无需CPU介入关键路径的不同设计和机制。我们首先介绍主机运行时和系统级设计,以解决第4.2节中描述的内存一致性挑战。然后我们讨论GPU端运行时架构和用于优化性能并减少GPU准备网络数据包延迟的模板方法。图3突出了支持GIO的关键数据结构及其在内存中的位置。在解释GIO的工作原理时,我们将参考此图。
CPU端运行时
CPU端运行时的职责。CPU负责初始化和管理网络资源,以及网络和GPU内存的分配。如图2所示,任何GIO代码都将通过主机端API调用shmem_init()
来初始化运行时。在shmem_init()
期间,我们执行图3中突出显示并在此处描述的步骤。
初始化步骤。我们首先创建网络资源(即SQ和CQ)并建立它们之间的连接。由于GIO使用工作组粒度,我们为GPU上的每个工作组创建一个SQ和一个CQ。我们依赖InfiniBand Direct-Verbs【【32,Diret Verbs,2019,Linux Man Pages】】机制直接与NIC硬件和驱动程序交互。我们设计了回调函数,允许NIC驱动程序在GPU内存上分配这些队列1
。接下来,我们向NIC驱动程序查询队列的地址以及与每个QP关联的门铃(doorbell)。然后,我们通过提取物理地址并将其映射到GPU的虚拟内存子系统,将这些门铃暴露给GPU2
。这些信息存储在一个句柄(handle)结构中,我们通过内核启动将其传递给GPU端运行时3
。一旦不同QP之间的连接建立,CPU就在GPU上分配对称堆,并将此内存注册到NIC以允许直接的RDMA访问。类似地,我们将PPB的内存映射控制寄存器的物理地址映射到GPU和NIC,以便两个设备都可以控制PPB4
。最后,我们从CPU异步准备网络模板,并按第5.3节所述填充每个队列5
。
图 4. GIO运行时、GPU驱动和NIC驱动之间的系统级交互。
暴露和控制PPB
PPB_MAP特性。为了向GPU SIMD引擎暴露PPB的控制寄存器,我们设计并增强了GPU驱动程序(amdgpu驱动)的一个新功能,我们称之为PPB_MAP
,它将PPB的内存映射I/O(MMIO)页面映射到GPU的虚拟地址空间。这个映射是在Linux内核和GPU驱动程序的协助下完成的,它在GPU页表中创建一个新条目,映射到相同的物理地址。此外,为了避免授予用户对所有GPU MMIO寄存器的完全访问权限,GPU驱动程序被更新以将PPB的寄存器提取到一个空页面中。
NIC访问PPB寄存器。正如我们在第4.2节中提到的,单边编程模型需要写后写(WaW)顺序,这要求NIC访问PPB的控制寄存器。通常,为了允许NIC访问内存,我们需要向NIC驱动程序注册该内存。这个注册过程涉及NIC驱动程序请求Linux系统锁定内存区域并提供与该区域虚拟地址(VA)关联的物理地址(PA)。然而,由于PPB寄存器是MMIO页面,注册将失败,因为Linux内存管理系统不管理设备MMIO页面。
PPB_MAP的实现机制。为了规避这个限制,我们提出的PPB_MAP
通过拦截注册请求,向驱动程序提供PPB的PA。这种拦截是通过PeerDirect接口【【20,How To Implement PeerDirect Client using MLNX_OFED,2018,Mellanox】】在NIC驱动程序中以回调的形式实现的。图4突出了NIC驱动程序、GPU驱动程序、PPB_MAP
和GIO运行时之间的交互步骤。首先,在GPU驱动程序启动/加载时,PPB_MAP
函数开始向用户暴露PPB的MMIO控制寄存器,并为节点中的每个GPU创建PPB的VA到PA转换的映射。接下来,我们将PPB_MAP
注册为NIC驱动程序的回调。一旦PPB的MMIO空间注册到NIC驱动程序,驱动程序就与PPB_MAP
交互以检索PA。然后,NIC驱动程序将这个VA到PA的转换插入到NIC的TLB中,以允许它访问PPB寄存器来执行shmem_fence()
,如第4.2节所讨论的。所有这些步骤都在模块加载期间或CPU端GIO运行时初始化期间执行,并且不在执行的关键路径上。
绕过GPU的L2缓存
L2缓存的问题。如第4.2节所讨论,GPU的L2缓存与系统其余部分不是相干的。不幸的是,与PPB不同,没有可以用来刷新L2缓存的MMIO寄存器,并且仅仅为了刷新L2缓存而启动一个新内核的开销太高。
使用不可缓存页面。为了满足绕过GPU L2缓存以处理由网络为RDMA操作访问的数据的需求,GPU驱动程序被扩展以提供分配具有不可缓存页面(UC)的GPU内存的能力。对于UC页面,来自SIMD的存储和加载将绕过L2并直接进入内存。这可能会降低应用程序的性能,我们将在第6节探讨使用不可缓存页面的影响。
特性可用性。大部分PPB_MAP
和UC页面映射功能已在amdgpu驱动程序中提供,从ROCm 2.5开始。
GPU端运行时
初始化与上下文管理。为了减少对句柄的内存访问延迟,在GPU运行时初始化期间,每个工作组将相应的句柄信息从GPU全局内存复制到LDS暂存器内存中,如图3中的6
所示。然后,我们将这个本地句柄用作我们为每个OpenSHMEM API调用传递的OpenSHMEM上下文。除了关于网络队列、NIC门铃和PPB寄存器的信息外,本地上下文还跟踪队列的索引。
网络操作执行流程。当一个GPU工作组执行一个转换为网络操作的OpenSHMEM调用时,它首先在其SQ中定位下一个网络命令包的位置,并用动态信息更新该包。其次,它将通过对PPB的控制寄存器执行写操作来使PPB缓存无效,这将刷新GPU的L2缓存。最后,该工作组敲响与SQ关联的NIC门铃。
等待操作完成。类似地,当一个工作组通过shmem_quiet()
API等待一个网络操作完成时,它会定位CQ中的下一个条目,并轮询该内存,等待NIC写入完成命令。
栅栏操作实现。正如第4.2节所建议的,为了在shmem_fence()
操作期间保证远程GPU的顺序,我们实现shmem_fence()
作为一个到远程GPU的PPB寄存器的RDMA写操作,以刷新其PPB缓存。
GIO网络模板化设计
现有方案的高延迟问题。如第1节所述,先前关于原生GPU网络的研究探讨了将整个网络协议栈移植到GPU【【7,GPUrdma: GPUside Library for High Performance Networking from GPU Kernels,2016,ROSS】,【28,GGAS: Global GPU Address Spaces for Eicient Communication in Heterogeneous Clusters,2013,CLUSTER】】。这些设计的通信发起延迟非常高。高延迟的原因是准备网络包主要是填充包的不同字段的一系列串行内存存储操作。这些访问由GPU上的单个执行线程执行。虽然GPU旨在通过线程间隐藏内存延迟来最大化吞吐量,但它们难以隐藏单个线程中一系列内存操作的延迟。
模板化设计。为了避免这种高延迟,我们提出了一种依赖于模板化和从CPU预提交网络包的设计。主要思想源于这样一个事实:构建网络包所需的大部分信息是静态的,并且在运行时初始化时已知;只有少数信息是动态的,例如源地址、目标地址和大小。我们当前的设计使用CPU在关键路径之外准备包含静态信息的网络包模板。这使得GPU线程只需更新动态包信息并敲响NIC的门铃。通过模板化,GPU线程现在只需执行几次存储操作,从而显著减少了发起网络操作的延迟。
A4 实验环境
硬件配置:
* 平台: 实验在最多4个节点上进行。
* CPU: 每个节点包含双插槽10核CPU。
* GPU: 每个节点配备一块AMD Radeon MI25 GPU。
* 网络: 节点间通过Connect-X4 InfiniBand网络连接。
软件配置:
* GPU计算平台: 使用AMD ROCm平台,版本为2.4。
* 网络协议栈: Mellanox OFED 4.5。
* 驱动和运行时: 实验实现依赖于对驱动和运行时的补丁。
实验基线:
为了进行对比,定义了以下几种模式:
1. GPU Initiated OpenSHMEM (GIO): 本文提出的设计,通信在内核内直接发起,并使用网络包模板化技术。包含第5节讨论的所有特性。
2. Existing Intra-Kernel Networking (IKN): 代表现有的核内网络通信方法【【8,dCUDA: Hardware Supported Overlap of Computation and Communication,2016,SC】,【16,ComP-Net: Command Processor Networking for Eicient Intra-kernel Communications on GPUs,2018,PACT’18】,【31,Gravel: Fine-Grain GPU-Initiated Network Messages,2017,SC】】,这类方法依赖CPU辅助线程代表GPU执行网络操作。为公平比较,此实现包含了GIO中的数据正确性保障技术。值得注意的是,该参考版本的IKN性能优于原始的同类方法【【7,GPUrdma: GPUside Library for High Performance Networking from GPU Kernels,2016,ROSS】,【12,GPUnet: Networking Abstractions for GPU Programs,2014,OSDI】,【13,Analyzing Put/Get APIs for Thread-Collaborative Processors,2014,ICPP Workshops】,【14,Analyzing Communication Models for Distributed Thread-collaborative Processors in Terms of Energy and Time,2015,ISPASS】,【28,GGAS: Global GPU Address Spaces for Eicient Communication in Heterogeneous Clusters,2013,CLUSTER】,【29,Ininiband-Verbs on GPU: A Case Study of Controlling an Ininiband Network Device from the GPU,2014,IPDPSW】】。
3. Inter-K: 传统的GPU网络通信模式,CPU负责网络控制路径。主机启动内核进行计算,所有网络通信通过内核边界的CPU端MPI调用进行。
4. Inter-K-Overlap: 优化的传统模式,通信仍在内核边界进行,但通过异步MPI调用和多流GPU技术来重叠计算与通信。
A4 实验结果
微基准测试
图 5. GIO与其他基线的微基准评估。
实验内容:
测量远程Put()
操作的延迟。所有实现都能达到峰值吞吐量,因此省略了带宽分析。
实验结果与分析:
* 单工作组延迟 (图5a):
* 与无GPU的CPU版本(Inter-K)相比,GIO的4字节延迟(5.15µs)略高于CPU(2.8µs),因为单个GPU线程比CPU线程慢。
* GIO的延迟比IKN低2倍,证明了模板化设计和直接GPU-NIC交互在降低网络操作发起延迟方面的有效性。
* GIO的延迟比包含空内核启动开销的Inter-K-Empty低3倍,因为它避免了为通信而启动/结束内核的开销。
* 多工作组延迟 (图5b):
* 实验通过增加工作组数量来评估GIO的Put()
延迟。
* 结果显示,只要网络未饱和,单个工作组的延迟不受GPU上其他工作组数量的显著影响,这得益于每个工作组拥有独立的网络资源(如QP)。
* 对于大消息,工作组数量会影响单个工作组感知的延迟,因为网络成为瓶颈,增加通信工作组数量会导致资源等待。
Jacobi 2D 模板计算
实验内容:
在一个表现出规则通信模式的Jacobi松弛问题上评估GIO的性能。算法包括本地计算、邻居间的光环交换(halo exchange)和残差计算。
图 6. 不同GPU网络技术在Jacobi Stencil上的弱扩展性测试,每个GPU问题规模为2K * 2K。
实验结果与分析:
* 弱扩展性 (图6):
* 在1-4个GPU节点上进行弱扩展测试(每个GPU处理2K*2K数据)。GIO性能最佳,并展现出线性的性能扩展。
* 在4个GPU节点上,GIO比基础的Inter-K版本性能高出40%,因为它能透明地重叠计算与通信,无需用户显式操作。
* GIO的性能与需要复杂编程才能实现重叠的Inter-K-Overlap相当,但GIO极大地提升了程序员的生产力。
* GIO同样优于IKN,后者因CPU-GPU同步开销高而性能稍逊于Inter-K。
图 7. 每个GPU问题规模为2K * 2K的Jacobi Stencil性能分解。
- 性能分解 (图7):
- GIO的性能优势主要来自计算与通信的重叠以及消除了Inter-K和Inter-K-Overlap都存在的内核启动开销。
图 8. 不同GPU网络技术在各种模板尺寸下的性能。
- 不同问题规模下的性能 (图8):
- 在4节点集群上,GIO在所有输入规模下均优于Inter-K和IKN。
- 相比Inter-K,GIO在1K*1K、2K*2K和4K*4K问题规模上分别提升了57%、40%和18%的性能。随着计算通信比的增加,性能增益减小。
- GIO运行时的计算开销可忽略不计,其计算性能与Inter-K的计算阶段相当。
- IKN因通信开销过高而性能最差。
稀疏三角求解器 (SpTS)
实验内容:
在一个展现出不规则和动态通信模式的SpTS应用上评估GIO。该应用采用“无同步”算法,非常适合核内通信模型。
图 9. SpTS算法图示,彩色箭头表示依赖关系。
表 1. 稀疏三角求解器(SpTS)应用的输入矩阵特性
图 10. 稀疏三角求解器(SpTS)应用的性能评估。
实验结果与分析:
* 可扩展性 (图10):
* 对于中到大型输入矩阵,GIO展现出优异的可扩展性,在4个GPU节点上实现了最高2.8倍的加速(70%的并行效率)。例如,对于road_central
矩阵,执行时间从单节点的557ms降低到4节点的196ms。
图 11. GIO相对于IKN的加速评估。
- 与IKN的性能对比 (图11):
- GIO的性能显著优于IKN。即使在单GPU上,GIO也因其较低的运行时开销而胜出。
- 对于小矩阵,GIO在2节点上性能提升高达3.7倍。对于大矩阵(如
road_central
),GIO在2、3、4个GPU节点上分别带来了38%、35%和44%的性能提升,显示出其低延迟网络操作的优势随规模扩大而增强。
表 2. 在SpTS中为通信缓冲区禁用GPU L2缓存的影响。
- L2缓存绕过开销 (表2):
- 评估为网络缓冲区绕过GPU L2缓存的性能影响。
- 结果显示,对于SpTS应用,性能开销很小,不超过9%。尽管如此,作者仍建议下一代GPU硬件提供更细粒度的L2缓存控制,以实现更自然的GPU-NIC交互。
A5 结论
本文提出了GIO,一个新颖的以GPU为中心的分布式编程模型和运行时系统,它通过核内网络通信技术,将GPU提升为网络中的一等公民。GIO的核心创新在于:
- 低延迟通信: 采用了一种新颖的网络包模板化方法,显著降低了GPU发起通信的延迟。
- 解决内存一致性: 深入分析了GPU与NIC共享数据时面临的内存一致性挑战,并设计了相应的编程模型、运行时和系统级方案来克服这些限制,确保了数据的正确性。
实验结果表明,GIO不仅提升了程序员的生产力,还在多种应用中取得了显著的性能提升:
* 对于模板计算等规则应用,性能提升高达40%。
* 对于稀疏三角求解器(SpTS)等不规则应用,与现有的核内网络设计相比,性能提升高达44%,并且相对于单节点设计实现了高达70%的并行效率。
GIO是推动GPU成为网络一等公民的重要一步。未来的工作将继续研究GIO,包括将更多应用移植到GIO上,并在更大规模的系统上进一步验证其可扩展性。
💬 评论讨论
欢迎在这里分享您的想法和见解!