揭秘GPU虚拟化,算力隔离,和最新技术突破qGPU

更新时间:2023-07-08 05:56:41 阅读: 评论:0

揭秘GPU虚拟化,算⼒隔离,和最新技术突破qGPU
原⽂:
〇、本⽂写作背景
⼤约 2 年前,在腾讯内⽹,笔者和很多同事讨论了 GPU 虚拟化的现状和问题。从那以后,出现了⼀些新的研究⽅向,并且,有些业界变化,可能会彻底颠覆掉原来的⼀些论断。
但这⾥并不是要重新介绍完整的 GPU 虚拟化的⽅案谱系。⽽是,我们将聚焦在英伟达 GPU + CUDA 计算领域,介绍下我们最新的技术突破 qGPU,以及它的意义究竟是什么。关于 GPU 虚拟化的历史性介绍,我将直接摘抄当时的讨论。
这也不是⼀篇介绍 TKE qGPU 产品特性的⽂章。⽽是,我们将潜⼊到前所未有的深度,去探索 GPU 调度和 QoS 的本质。本⽂也不是巨细靡遗的系统性探索,但你可以在这⾥看到别处不曾出现过的知识。
本⽂涉及对⼀些⼚商的推测性技术介绍,不保证准确性。
⼀、术语介绍
吹擂GPU ————— Graphics Processing Unit,显卡
CUDA ———— Compute Unified Device Architecture,英伟达 2006 年推出的计算 API
VT/VT-x/VT-d — Intel Virtualization Technology。-x 表⽰ x86 CPU,-d 表⽰ Device。
SVM ————— AMD Secure Virtual Machine。AMD 的等价于 Intel VT-x 的技术。
EPT ————— Extended Page Table,Intel 的 CPU 虚拟化中的页表虚拟化硬件⽀持。
NPT ————— Nested Page Table,AMD 的等价于 Intel EPT 的技术。音乐教案大班
SR-IOV ——— Single Root I/O Virtualization。PCI-SIG 2007 年推出的 PCIe 虚拟化技术。
PF ————— Physical Function,亦即物理卡
VF ————— Virtual Function,亦即 SR-IOV 的虚拟 PCIe 设备
MMIO ——— Memory Mapped I/O。设备上的寄存器或存储,CPU 以内存读写指令来访问。
CSR ———— Control & Status Register,设备上的⽤于控制、或反映状态的寄存器。CSR 通常以 MMIO 的⽅式访问。
UMD ———— Ur Mode Driver。GPU 的⽤户态驱动程序,例如 CUDA 的 UMD 是 libcuda.so
KMD ———— Kernel Mode Driver。GPU 的 PCIe 驱动,例如英伟达 GPU 的 KMD 是 nvidia.ko
GVA ———— Guest Virtual Address,VM 中的 CPU 虚拟地址
GPA ———— Guest Physical Address,VM 中的物理地址
HPA ———— Host Physical Address,Host 看到的物理地址
IOVA ———— I/O Virtual Address,设备发出去的 DMA 地址
PCIe TLP —— PCIe Transaction Layer Packet
BDF ———— Bus/Device/Function,⼀个 PCIe/PCI 功能的 ID
MPT ———— Mediated Pass-Through,受控直通,⼀种设备虚拟化的实现⽅式
MDEV ——— Mediated Device,Linux 中的 MPT 实现
PRM ———— Programming Reference Manual,硬件的编程⼿册
MIG ———— Multi-Instance GPU,Ampere 架构⾼端 GPU 如 A100 ⽀持的⼀种 hardware partition ⽅案
⼆、GPU 虚拟化的历史和谱系
2.1 GPU 能做什么
GPU 天然适合向量计算。常⽤场景及 API:
此外还有加解密、哈希等场景,例如近些年来的挖矿。渲染是 GPU 诞⽣之初的应⽤: GPU 的 G 就是 Graphics —— 图形。
桌⾯、服务器级别的 GPU,长期以来仅有三家⼚商:
1. 英伟达:GPU 的王者。主要研发⼒量在美国和印度。
2. AMD/ATI:ATI 于 2006 年被 AMD 收购。渲染稍逊英伟达,计算的差距更⼤。
3. Intel:长期只有集成显卡,近年来开始推独⽴显卡。
2006 这⼀年,GPU ⼯业界发⽣了三件⼤事: ATI 被 AMD 收购;nVidia 黄仁勋提出了 CUDA 计算;Intel 宣布要研发独⽴显卡。
不惮⽇光之下并⽆新事。如同经常发⽣的,这些事有成功有失败: Intel 很快就放弃了它的独⽴显卡,直到 2018 才终于明⽩过来⾃⼰到底放弃了什么,开始决⼼⽣产独⽴显卡;AMD 整合 ATI 不太成功,整个公司差点被拖死,危急时公司股票跌到不⾜ 2 美元;⽽当时不被看好的CUDA,则在⼏年后取得了不可思议的成功。
从 2012 年开始,⼈⼯智能领域的深度学习⽅法开始崛起,此时 CUDA 受到青睐,并很快统治了这个领域。
2.2 系统虚拟化和 OS 虚拟化
系统虚拟化演化之路,起初是和 GPU 的演化完全正交的:
1998 年,VMWare 公司成⽴,采⽤ Binary Translation ⽅式,实现了系统虚拟化。
2001 年,剑桥⼤学 Xen Source,提出了 PV 虚拟化(Para-Virtualization),亦即 Guest-Host 的主动协作来实现虚拟化。梦见很大的蛇
2005 年,Intel 提出了 VT,最初实现是安腾 CPU 上的 VT-i (VT for Itanium),很快就有了 x86 上的 VT-x。
2007 年,Intel 提出了 VT-d (VT for Device),亦即 x86 上的 IOMMU。
2008 年,Intel 提出了 EPT,⽀持了内存虚拟化。
2010 年,Linux 中的 PV Hypervisor lguest 的作者,Rusty Rusll(他更有名的作品是 iptables/netfilter),提出了 VirtIO,⼀种 Guest-Host 的 PV 设备虚拟化⽅案。
应该可以说,在 PV 时代和 Binary Translation 时代,虚拟化是危险的。只有当 VT 在硬件层⾯解决了 CPU 的隔离、保证了安全性之后,公有云才成为可能。VT-x 于 2005 ~ 2006 年出现,亚马逊 AWS 于 2006 年就提出云计算,这是⾮常有远见的。
系统的三个要素: CPU,内存,设备。CPU 虚拟化由 VT-x/SVM 解决,内存虚拟化由 EPT/NPT 解决,这些都是⾮常确定的。但设备虚拟化呢?它的情况要复杂的多,不管是 VirtIO,还是 VT-d,都不能彻底解决设备虚拟化的问题,这些我们稍后还会谈到。
除了这种完整的系统虚拟化,还有⼀种也往往被称作「虚拟化」的⽅式: 从 OS 级别,把⼀系列的 library 和 process 捆绑在⼀个环境中,但所有的环境共享同⼀个 OS Kernel。
严格来说,这种容器技术,和以 KVM 为代表的系统虚拟化,有着本质的区别。随着容器的流⾏,「虚拟化」这个术语,也被⽤来指称这种OS 级别的容器技术。因此我们也从众,把它也算作虚拟化的⼀种 —— 只不过为了区分,称之为「OS 虚拟化」。
这种 OS 虚拟化最初于 2005 年,由 Sun 公司在 Solaris 10 上实现,名为「Solaris Zone」。Linux 在 2007 ~ 2008 开始跟进,接下来有了 LXC 容器等;到了 2013 年,Docker 横空出世,彻底改变了软件分发的⽣态,成为事实上的标准。
2.3 GPU 虚拟化的谱系
重置系统
2.3.1 作为 PCIe 设备的 GPU
不考虑嵌⼊式平台的话,那么,GPU ⾸先是⼀个 PCIe 设备。GPU 的虚拟化,还是要⾸先从 PCIe 设备虚拟化⾓度来考虑。
那么⼀个 PCIe 设备,有什么资源?有什么能⼒?
2 种资源:
配置空间
MMIO
(有的还有 PIO 和 Option ROM,此略)
2 种能⼒:
中断能⼒
DMA 能⼒
⼀个典型的 GPU 设备的⼯作流程是:
1. 应⽤层调⽤ GPU ⽀持的某个 API,如 OpenGL 或 CUDA小鸟头饰
2. OpenGL 或 CUDA 库,通过 UMD (Ur Mode Driver),提交 workload 到 KMD (Kernel Mode Driver)
3. KMD 写 CSR MMIO,把它提交给 GPU 硬件
4. GPU 硬件开始⼯作... 完成后,DMA 到内存,发出中断给 CPU
5. CPU 找到中断处理程序 —— KMD 此前向 OS Kernel 注册过的 —— 调⽤它
6. 中断处理程序找到是哪个 workload 被执⾏完毕了,...最终驱动唤醒相关的应⽤
2.3.2 PCIe 直通
我们⾸先来到 GPU 虚拟化的最保守的实现: PCIe 设备直通。
如前述,⼀个 PCIe 设备拥有 2 种资源、2 种能⼒。你把这 2 种资源都(直接或间接地)交给 VM、针对这 2 种能⼒都把设备和 VM 接通,那么,VM 就能完整使⽤这个 PCIe 设备,就像在物理机上⼀样。这种⽅案,我们称之为 PCIe 直通(PCIe Pass-Through)。它只能1:1,不⽀持 1:N。其实并不能算真正的虚拟化,也没有超卖的可能性。
VM 中,使⽤的是原⽣的 GPU 驱动。它向 VM 内核分配内存,把 GPA 填⼊到 GPU 的 CSR 寄存器,GPU ⽤它作为 IOVA 来发起 DMA 访问,VT-d 保证把 GPA 翻译为正确的 HPA,从⽽ DMA 到达正确的物理内存。
PCIe 协议,在事务层(Transaction Layer),有多种 TLP,DMA 即是其中的⼀种: MRd/MWr。在这种 TLP 中,必须携带发起者的Routing ID,⽽在 IOMMU 中,就根据这样的 Routing ID,可以使⽤不同的 IOMMU 页表进⾏翻译。
很显然,PCIe 直通只能⽀持 1:1 的场景,⽆法满⾜ 1:N 的需求。
2.3.3 SR-IOV
那么,业界对 1:N 的 PCIe 虚拟化是如何实现的呢?我们⾸先就会想到 SR-IOV。SR-IOV 是 PCI-SIG 在 2007 年推出的规范,⽬的就是PCIe 设备的虚拟化。SR-IOV 的本质是什么?考虑我们说过的 2 种资源和 2 种能⼒,来看看⼀个 VF 有什么:
配置空间是虚拟的(特权资源)
MMIO 是物理的
中断和 DMA,因为 VF 有⾃⼰的 PCIe 协议层的标识(Routing ID,就是 BDF),从⽽拥有独⽴的地址空间。
小米查真伪
那么,什么设备适合实现 SR-IOV?其实⽆⾮是要满⾜两点:
硬件资源要容易 partition
⽆状态(⾄少要接近⽆状态)
常见 PCIe 设备中,最适合 SR-IOV 的就是⽹卡了: ⼀或多对 TX/RX queue + ⼀或多个中断,结合上⼀个 Routing ID,就可以抽象为⼀个 VF。⽽且它是近乎⽆状态的。
试考虑 NVMe 设备,它的资源也很容易 partition,但是它有存储数据,因此在实现 SR-IOV ⽅⾯,就会有更多的顾虑。
回到 GPU 虚拟化:为什么 2007 年就出现 SR-IOV 规范、直到 2015 业界才出现第⼀个「表⾯上的」SRIOV-capable GPU【1】?这是因为,虽然 GPU 基本也是⽆状态的,但是它的硬件复杂度极⾼,远远超出 NIC、NVMe 这些,导致硬件资源的 partition 很难实现。
注释
【1】 AMD S7150 GPU。腾讯云 GA2 机型使⽤。
表⾯上它⽀持 SR-IOV,但事实上硬件只是做了 VF 在 PCIe 层的抽象。Host 上还需要⼀个 Virtualization-Aware 的 pGPU 驱动,负责VF 的模拟和调度。
2.3.4 API 转发
因此,在业界长期缺乏 SRIOV-capable GPU、⼜有强烈的 1:N 需求的情形下,就有更 high-level 的⽅案出现了。我们⾸先回到 GPU 应⽤的场景:
1. 渲染(OpenGL、DirectX,etc.)
2. 计算(CUDA,OpenCL)
3. 媒体编解码()
业界就从这些 API ⼊⼿,在软件层⾯实现了「GPU 虚拟化」。以 AWS Elastic GPU 为例:
VM 中看不到真的或假的 GPU,但可以调⽤ OpenGL API 进⾏渲染
在 OpenGL API 层,软件捕捉到该调⽤,转发给 Host
Host 请求 GPU 进⾏渲染
Host 把渲染的结果,转发给 VM
API 层的 GPU 虚拟化是⽬前业界应⽤最⼴泛的 GPU 虚拟化⽅案。它的好处是:
灵活。1:N 的 N,想定为多少,软件可⾃⾏决定;哪个 VM 的优先级⾼,哪个 VM 的优先级低,同理。
不依赖于 GPU 硬件⼚商。微软、VMWare、Citrix、华为……都可以实现。这些 API 总归是公开的。
不限于系统虚拟化环境。容器也好,普通的物理机也好,都可以 API 转发到远端。
纯粹美
缺点呢?
复杂度极⾼。同⼀功能有多套 API(渲染的 DirectX 和 OpenGL),同⼀套 API 还有不同版本(如 DirectX 9 和 DirectX 11),兼容性就复杂的要命。
功能不完整。计算渲染媒体都⽀持的 API 转发⽅案,还没听说过。并且,编解码甚⾄还不存在业界公⽤的 API!【1】
注释
【1】 Vulkan 的编解码⽀持,spec 刚刚添加,有望被所有 GPU ⼚商⽀持。见下「未来展望」部分。
2.3.5 MPT/MDEV/vGPU
鉴于这些困难,业界就出现了 SR-IOV、API 转发之外的第三种⽅案。我们称之为 MPT(Mediated Pass-Through,受控的直通)。MPT 本质上是⼀种通⽤的 PCIe 设备虚拟化⽅案,甚⾄也可以⽤于 PCIe 之外的设备。它的基本思路是:
敏感资源如配置空间,是虚拟的
关键资源如 MMIO(CSR 部分),是虚拟的,以便 trap-and-emulate
性能关键资源如 MMIO(GPU 显存、NVMe CMB 等),硬件 partition 后直接赋给 VM
Host 上必须存在⼀个 Virtualization-Aware 的驱动程序,以负责模拟和调度,它实际上是 vGPU 的 device-model
这样,VM 中就能看到⼀个「看似」完整的 GPU PCIe 设备,它也可以 attach 原⽣的 GPU 驱动。以渲染为例,vGPU 的基本⼯作流程是:
1. VM 中的 GPU 驱动,准备好⼀块内存,保存的是渲染 workload
2. VM 中的 GPU 驱动,把这块内存的物理地址(GPA),写⼊到 MMIO CSR 中
3. Host/Hypervisor/驱动: 捕捉到这次的 MMIO CSR 写操作,拿到了 GPA
4. Host/Hypervisor/驱动: 把 GPA 转换成 HPA,并 pin 住相应的内存页
5. Host/Hypervisor/驱动: 把 HPA(⽽不是 GPA),写⼊到 pGPU 的真实的 MMIO CSR 中
6. pGPU ⼯作,完成这个渲染 workload,并发送中断给驱动
7. 驱动找到该中断对应哪个 workload —— 当初我是为哪个 vGPU 提交的这个 workload?—— 并注
⼊⼀个虚拟的中断到相应的 VM
8. VM 中的 GPU 驱动,收到中断,知道该 workload 已完成、结果在内存中
这就是 nVidia GRID vGPU、Intel GVT-g(KVMGT、XenGT)的基本实现思路。⼀般认为 graphics stack 是 OS 中最复杂的,加上虚拟化之后复杂度更是暴增,任何地⽅出现⼀个编程错误,调试起来都是⽆⽐痛苦。但只要稳定下来,这种 MPT ⽅案,就能兼顾 1:N 灵活性、⾼性能、渲染计算媒体的功能完整性...是不是很完美?
其实也不是。
该⽅案最⼤的缺陷,是必须有⼀个 pGPU 驱动,负责 vGPU 的模拟和调度⼯作。逻辑上它相当于⼀个实现在内核态的 device-model。⽽且,由于 GPU 硬件通常并不公开其 PRM,所以事实上就只有 GPU ⼚商才有能⼒提供这样的 Virtualization-Aware pGPU 驱动。使⽤了⼚商提供的 MPT ⽅案,事实上就形成了对⼚商的依赖。
2.3.6 SR-IOV: revisited
重新回到 GPU 的 SR-IOV。AMD 从 S7150 开始、英伟达从 Turing 架构开始,数据中⼼ GPU 都⽀持了 SR-IOV。但是 again,它不是NIC 那样的 SR-IOV,它需要 Host 上存在⼀个 vGPU 的 device-model,来模拟从 VM 来的 VF 访问。
所以事实上,到⽬前为⽌,GPU 的 SR-IOV 仅仅是封装了 PCIe TLP 层的 VF 路由标识、从⽽规避了 runtime 时的软件 DMA 翻译,除此之外,和基于 MDEV 的 MPT ⽅案并⽆本质的不同。
2.3.7 谱系表
在介绍完了上述的这些⽅案后,我们重新看下 CUDA 计算、OpenGL 渲染两种场景的软件栈,看看能发现什么:
CUDA 计算 stack:

本文发布于:2023-07-08 05:56:41,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1084964.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:虚拟化   设备   实现
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图