异构计算云服务和 AI 加速器(四):FPGA 虚拟化技术
🚀
FPGA
(Field-Programmable Gate Array
,现场可编程门阵列)是一种可重构的半导体芯片,允许用户根据需要动态配置硬件逻辑,从而实现定制化的数字电路功能。它介于通用处理器(如 CPU)和专用芯片(如 ASIC)之间,兼具灵活性和高性能计算能力。
将 FPGA 的高性价比算力通过云输出,使得 FPGA 的算力普惠化、平民化,这是 FPGA as a Service
的核心出发点和立足点。同时,云上使用 FPGA 与 FPGA 的传统使用方式也有着非常大的区别。FPGA as a Service
的核心就是 FPGA 虚拟化技术。
目前 FPGA 虚拟化技术还在发展初期,近几年随着云计算和 AI 技术的发展,才逐渐成为工业和学术领域研究的热点。关于 FPGA 虚拟化技术的介绍文献也比较少,关于 FPGA 虚拟化技术的发展历史,目前比较全面的总结可以参考 2018 年由 Manchester 大学学生发表的一篇 IEEE 论文《A Survey on FPGA Virtualization》,文中提到早在 2004 年由 Plessl 和 Platzner 发表的一篇论文《Virtualization of Hardware Introduction and Survey》中提到过 FPGA 虚拟化技术的概念,将 FPGA 虚拟化技术分为 时域划分(Temporal Partitioning
)、虚拟化执行(Virtualized Execution
)和 虚拟机(Virtual Machines
)三种。
- 时域划分 早期主要解决设备容量问题,是将大规模的应用设计拆分为几个小设计,然后将每个设计烧写在单个 FPGA 上顺序执行。时域划分技术如下图所示,主要包括 网表划分、数据流图划分 和 CDFG 划分。随着数据量和计算复杂度的增加,单片 FPGA 已经无法满足一个应用的需求,需要多片 FPGA 并行完成,虚拟化技术逐渐打破了时间和空间维度的限制,就像大型数据中心的应用场景:多片 FPGA 并行执行同一个任务,并可以及时切换到下一个任务。
-
虚拟化执行 是把一个应用分成几个有关联的任务,并通过一个抽象层来管理和调度它们,其目的是在一定程度上实现 设备无关性(
Device Independence
),从而解决资源管理和安全隔离问题,还可以提高开发效率,比较典型的例子是 PipeRench 项目,此项目成功研发了 Kilocore 芯片,它内置了一个 PowerPC 处理器,实现了硬件虚拟化,并可以动态配置,从而解决 FPGA 的资源限制问题。 -
虚拟机 通过一个抽象架构来描述应用从而彻底实现设备无关性。起初,虚拟机的概念用来表示 FPGA 的静态架构,譬如 Shell 或者 vFPGA 的 Hypervisor,并不是我们现在理解的虚拟机概念。现在的 FPGA Overlay 技术是应用比较广泛的 FPGA 虚拟化方法之一,它是位于 FPGA 硬件层之上、并连接顶层应用的虚拟可编程架构,实现了对 FPGA 底层硬件资源的抽象化和虚拟化。FPGA Overlay 的具体实现方式有很多种,这里不详细介绍,其主要目的是为上层用户提供他们熟悉的编程架构与接口,比如通过 C 语言等高层语言对 Overlay 中的通用处理器等进行编程,而无须担心具体的硬件电路实现,这点类似 HLS。Overlay 实现了 FPGA 的硬件无关性,便于应用设计在不同 FPGA 架构间移植。另外,用户可以选择只编译自己改动的逻辑部分,在很大程度上缩短了 FPGA 的编译时间,也方便对应用进行调试和修改。但是在实际开发中,由于其引入的 Overlay 层并不能完全隐藏 FPGA 结构,而且此技术没有业界统一标准,所以会来带额外的开发难度和成本。
按照资源的抽象级别,FPGA 虚拟化技术分为三类,如下图所示。
- 资源级别(
Resource Level
):FPGA 上的资源可分为两种,一种是可配置的,一种是不可配置的,所以资源级别的虚拟化主要指架构虚拟化(增加一个抽象层)和I/O 虚拟化,比较典型的技术就是 FPGA Overlay 技术,I/O 虚拟化技术本质上跟 CPU/GPU 实现类似,比如 FPGA 云主机用到的设备透传功能。 - 单节点级别(
Node Level
):单节点指单片 FPGA,主要指具备资源管理功能的抽象层,包括 VMM(Virtual Machine Monitors,也叫 Hypervisor),Shell(FPGA OS或 Hypervisor-vFPGA)和调度管理,主要用于多租户场景,即 FPGA 云主机。 - 多节点级别(
Multi-Node Level
):多节点指由两片以上 FPGA 组成的 FPGA 集群,虚拟化的目的是在多片 FPGA 上完成同一个加速任务。其实现依赖 FPGA 互联功能,常见的有三种互联方式,如下图所示。
🚀 将加速器扩展到多片 FPGA 上的架构集合。此处
- a) 代表 FPGA 到 FPGA 通信;
- b) 展示了一种服务器-客户机架构,在这种架构中 FPGA 直接和服务器通信;
- c) 表示在服务器-客户机架构中,FPGA 作为客户机 CPU 的一个特殊设备。
FPGA 虚拟化技术比较典型的应用场景包括基于 OpenCL 实现的 MapReduce 框架和微软的 Catapult 项目。
从 FPGA 云主机的实现方式来说,FPGA 虚拟化指 I/O(PCIe 设备)虚拟化技术。
I/O 虚拟化技术,有些地方也叫 I/O 设备虚拟化技术,目前主流的模型实现方式有以下几种:
- 全模拟:纯软件实现,通常由虚拟化层(QEMU)完全模拟一个设备给虚拟机用,其优点是不需要修改操作系统内核和驱动,因此它是可移植性与兼容性最好的 I/O 设备虚拟模型。但是,这种实现模型性能不高,主要原因是:第一,软件模拟本身就无法具有很高的性能 ;第二,在这种实现方式中,I/O 请求的完成需要虚拟机与监视程序多次的交互,产生大量的上下文切换,开销巨大。
- Virtio 驱动半虚拟化:将设备虚拟的工作一拆为二,一部分在虚拟机内核中作为前端驱动,一部分放到虚拟化层上(通常是 QEMU)作为后端,前后端共享 Virtio 环协同完成任务。Virtio 前后端的技术只是减少了 VM Exit 和 VM Entry(Guest 和 Host 的上下文切换),并且使 Guest 和 Host 能通过并行处理 I/O 来提高吞吐量并减少延迟。但是,I/O 的路径并不比全虚拟化技术少。
- 硬件辅助虚拟化:借助硬件技术,如 Intel 的 VT-d 技术实现 PCI 设备直接挂载给虚拟机,常见的有设备直通和 SR-IOV。
纵观各大云服务提供商,FPGA 云服务器采用的都是 设备直通(Device Passthrough
),主要因为以下三点 :
- 一是 FPGA 的性能,客户考虑业务搬迁上云首先要做的就是对比,跟本地物理机比、跟竞品(如 GPU/ASIC)比。虚拟化必然导致部分的硬件性能损耗,1% 的性能损失都会增大客户拒绝使用 FPGA 云服务器的可能性 ;
- 二是应用场景,FPGA 比较适用于计算密集型和通信密集型任务。在大数据爆发的时代,很多应用都需要调度多片 FPGA 才能满足需求,将同一片 FPGA 共享给多个客户的需求并不强烈 ;
- 三是实现难度,分片 FPGA(
vFPGA
)的多租户场景,在安全和隔离的实现上,虽然可以复用 vGPU 方案,但是硬件逻辑开发的难度非常大。综合考虑,各大云服务提供商在FPGA 设备虚拟化时选择的都是性能损耗最小的设备直通方案。
设备直通技术:是将宿主机上的 PCIe 设备直接分配给客户机使用,虚拟机独占这个设备,在客户机进行对应的 I/O 操作时,不需要通过 VMM 或被 VMM 截获,所以设备性能几乎无损耗。设备直通技术的实现依赖 IOMMU 功能(隔离虚拟机对内存资源的访问),需要硬件支持,比如 Intel 平台的VT-d 技术。
说到 VT-d 技术,首先要解释下 DMA(直接内存读取),它是一种硬件机制,允许外围设备和主内存之间直接传输数据,不需要 CPU 参与,由此可以大大提高设备的吞吐量。I/O 虚拟化的关键在于解决 I/O 设备与虚拟机的数据交换问题,而这部分主要指 DMA 和中断请求(IRQ
)。只要解决好这两个方面的隔离、保护及性能问题,就是成功的 I/O 虚拟化。VT-d 通过重新设计 IOMMU 架构,在 CPU、内存和 I/O 设备之间增加了一个硬件设备,其主要功能是将 I/O 设备的 DMA 访问请求和中断请求重定向到 VMM 设定好的 VM 中,最终实现了 DMA 虚拟化,这项技术也叫 DMA 重映射。
阿里云 FPGA 云主机的设备直通方式采用的是 VFIO,这是一套用户驱动框架,通俗来讲就是一个设备驱动。在虚拟化情景下,VFIO 主要用来在用户实现设备直通,充分利用了 VT-d 技术提供的 DMA 重映射和中断重映射特性,在保证直通设备的DMA 安全性的同时其 I/O 性能接近物理设备。
总体来说,FPGA 板卡(PCIe 设备)的透传方式跟 GPU/NIC 等 PCIe 设备并无差别,鉴于 FPGA 本身的硬件特性和安全隔离要求,阿里云 FPGA 云服务器虽然采用了设备直通方式,但是并没有把 FPGA 设备功能完全暴露给虚拟机,而是将 PCIe 从功能角度划分为两个 PF(Physical Function):即 管理 PF(Management PF
)和 用户 PF(UserPF
),如下图所示。
- 管理 PF:提供 FPGA 各种控制功能,如 FPGA 镜像加载、状态监控等。例如,在 FPGA 云主机上,只有先发送加载请求,后台系统认证身份后,通过宿主机驱动才能发起加载操作。
- 用户 PF:对应的是逻辑功能接口,此功能会通过设备直通方式透传给虚拟机,用户可以使用官方提供的驱动访问设备,也可以自己开发。
PCIe 功能双 PF 的划分,在一定程度上保护了 FPGA 板卡不会被用户恶意烧写,从而降低了宿主机的停机风险,也保证了 FPGA as a Service
的可靠性。此方案的实现基于 FPGA 特殊的硬件特性(部分可重配置),主流云服务提供商的做法基本类似。
部分可重配置(Partial Reconfiguration
):在前面介绍 FPGA 虚拟化技术的时候提到过,其实现原理是将 FPGA 内部划分出多个区域,在 FPGA 运行时单独对这些区域进行编程和配置,以改变区域内电路的逻辑,但并不影响 FPGA 其他电路的正常运行。它可以实现时间域和空间域两个维度的任务切换,很多大型应用的逻辑都是利用 FPGA 这一特性实现的,如微软的 Catapult 项目同时提出了 Shell(不可配置区域)和 Role(可重配的逻辑单元)的概念。也有将这一特性应用在多租户场景下的,提出了vFPGA 的概念,即将一个 FPGA 共享给多个用户使用,如 IBM 的 CloudFPGA 项目。
各云服务提供商的 FPGA 云服务器也抓住了这一特性,将 FPGA 在逻辑上划分为 Shell(静态区)和用户逻辑(动态区)。
- 静态区:FPGA 的静态区主要包括 PCIe、DRAM、DMA 及中断等接口逻辑,一般由云服务提供商提供,主要负责 FPGA 管理功能。
- 用户逻辑:FPGA 的动态可重配置区域属于用户数据,即用户的知识产权(
IP
)。
阿里云 FPGA 云主机在 F3 实例设计时也提出了 Role 的概念,它是和 Shell 类似的封装,跟用户逻辑一样处于动态区域,其目的是简化 Shell 功能,以尽可能减少 Shell 升级。另外,通过 Role 实现了同一个 Shell 既可以支持 OpenCL 开发,也可以支持 RTL 开发的功能,同时降低了用户对 FPGA 的开发门槛。