代码改变世界

计算机组成原理 — GPU 图形处理器

2019-08-12 19:33  云物互联  阅读(3567)  评论(0编辑  收藏  举报

目录

显卡

显卡(Video card、Display card、Graphics card、Video adapter)是 PC(Personal Computer)最基本的组成部分之一,用途是将计算机系统所需要的显示信息进行转换,继而驱动显示器,并向显示器提供逐行或隔行扫描信号,控制显示器的正确显示,是连接显示器和个人计算机主板的重要组件,是 “人机对话” 的重要设备之一。

显卡是插在计算机主板扩展槽(现在一般是 PCI-E 插槽,此前还有 AGP、PCI、ISA 等插槽)上的外部设备。它主要负责把主机向显示器发出的显示信号转化为一般电器信号,使得显示器能明白个人计算机在让它做什么。显卡的主要芯片叫 “显示芯片”(Video chipset,也叫 GPU 或 VPU,图形处理器或视觉处理器),是显卡的主要处理单元。显卡上也有和计算机存储器相似的存储器,称为 “显示存储器”,简称显存。

早期的显卡只是单纯意义的显卡,只起到信号转换的作用。目前我们一般使用的显卡都带有 3D 画面运算和图形加速功能,所以也叫做 “图形加速卡” 或 “3D 加速卡”。PC 上最早的显卡是 IBM 在 1981 年推出的 5150 个人计算机上所搭载的 MDA 和 CGA 两款 2D 加速卡。

显卡通常由总线接口、PCB 板、显示芯片、显存、RAM DAC、VGA BIOS、VGA 功能插针、D-sub 插座及其他外围组件构成,现在的显卡大多还具有 VGA、DVI 显示器接口或者 HDMI 接口及 S-Video 端子和 Display Port 接口。

GPU

GPU(Graphic Processing Unit,计算机图形处理器)在 1999 年 8 月发表 NVIDIA GeForce 256 绘图处理芯片时首先提出的概念,而对手冶天科技(ATi,已被 AMD 收购)亦提出视觉处理器(VPU,Visual Processing Unit)概念。在此之前,计算机中处理影像输出的显示芯片,通常不被视为是一个独立的运算单元,也就是我们常说的 “集显”(集成显卡)。GPU 的提出让 “独显”(独立显卡)成为了可能。GPU 作为硬件显卡的 “心脏”,地位等同于 CPU 在计算机系统中的作用。GPU 使硬件显卡减少对 CPU 的依赖,并分担部分原本由 CPU 所担当的工作,尤其是在进行三维绘图运算时,功效更加明显。

GPU 也可以用来作为区分 2D 硬件显卡和 3D 硬件显卡的重要依据。2D 硬件显卡主要通过使用 CPU 来处理特性和 3D 图像,将其称作 “软加速”。3D 硬件显卡则是把特性和 3D 图像的处理能力集中到硬件显卡中,也就是 “硬件加速”。目前市场上流行的显卡多半是由 NVIDIA 及 ATi 这两家公司生产的。

使用 GPU 有两种方式,一种是开发的应用程序通过通用的图形库接口调用 GPU 设备,另一种是 GPU 自身提供 API 编程接口,应用程序通过 GPU 提供的 API 编程接口直接调用 GPU 设备。

在这里插入图片描述

GPU 与深度学习

深度学习是模拟人脑神经系统而建立的数学网络模型,这个模型的最大特点是,需要大数据来训练。因此,对电脑处理器的要求,就是需要大量的并行的重复计算,GPU 正好有这个专长,时势造英雄,因此,GPU 就出山担当重任了。

  • 训练:我们可以把深度学习的训练看成学习过程。人工神经网络是分层的、是在层与层之间互相连接的、网络中数据的传播是有向的。训练神经网络的时候,训练数据被输入到网络的第一层。然后所有的神经元,都会根据任务执行的情况,根据其正确或者错误的程度如何,分配一个权重参数(权值)。
  • 推理:就是深度学习把从训练中学习到的能力应用到工作中去。不难想象,没有训练就没法实现推断。我们人也是这样,通过学习来获取知识、提高能力。深度神经网络也是一样,训练完成后,并不需要其训练时那样的海量资源。

GPU 与 CPU 体系结构的区别

GPU 设计目的和 CPU 截然不同。CPU,如 Intel i5 或 i7 处理器,其内核数量较少,专为通用计算而设计,因此具有复杂的控制单元;而 GPU,是一种特殊类型的处理器,具有数百或数千个内核,经过优化,可并行运行大量计算,主要用来处理计算性强而逻辑性不强的计算任务,GPU 中可利用的处理单元可以更多的作为执行单元。因此,相较于 CPU,GPU 在具备大量重复数据集运算和频繁内存访问等特点的应用场景中具有无可比拟的优势。

由于图形渲染任务具有高度的并行性,因此 GPU 可以仅仅通过增加并行处理单元和存储器控制单元便可有效的提高处理能力和存储器带宽。虽然 GPU 在游戏中以 3D 渲染而闻名,但它们对运行分析、深度学习和机器学习算法尤其有用。GPU 能够让某些计算比传统 CPU 上运行相同的计算速度快 10 倍至 100 倍。

GPU 是并行编程模型,和 CPU 的串行编程模型完全不同,导致很多 CPU 上优秀的算法都无法直接映射到 GPU 上,并且 GPU 的结构相当于共享存储式多处理结构,因此在 GPU 上设计的并行程序与 CPU 上的串行程序具有很大的差异。GPU 主要采用立方环境的材质贴图、硬体 T&L(Transform and Lightning)、顶点混合、凹凸的映射贴图和纹理压缩、双重纹理四像素 256 位的渲染引擎等重要技术。

  • CPU 串行运算
    在这里插入图片描述

  • GPU 并行运算
    在这里插入图片描述

简单来说,CPU 是一个具有多种功能的优秀领导者。它的优点在于调度、管理、协调能力强,但计算能力一般。而 GPU 相当于一个接受 CPU 调度的 “拥有大量计算能力” 的员工

在这里插入图片描述

在这里插入图片描述
CPU 是一种低延迟的设计

  • CPU 有强大的 ALU(逻辑运算部件),时钟频率很高;
  • CPU 的容量较大的 Cache,一般包含 L1、L2 和 L3 三级高速缓存。其中 L3 可以达到 8MB,这些 Cache 占据相当一部分的片上空间;
  • CPU 有复杂的控制逻辑,例如:复杂的流水线(pipeline)、分支预测(branch prediction)、乱序执行(Out-of-order execution)等;

这些设计使得真正执行运算的 ALU 单元只占据了很小一部分的 CPU 片上空间。

在这里插入图片描述

GPU 是一种高吞吐的设计

  • GPU 有大量的 ALU;
  • Cache 很小,缓存的目的不是保存后面需要访问的数据的,而是为 Thread 提高服务的,这点和 CPU 不同;
  • 没有复杂的控制逻辑,没有分支预测等这些组件;

这样的设计,使得 GPU 擅长的是大规模的数据并行(Data-Parallel)的计算任务。

GPU 显存与 CPU 主存的区别

在这里插入图片描述
一般来说,CPU 和主存之间的带宽只有数十 GB/s。例如:Intel Xeon E5-2699 v3,内存带宽达到 68GB/s((2133 * 64 / 8)*4 MB/s)。
在这里插入图片描述
而 GPU 的高速缓存虽然较小,高速缓存与显存(上图中的 Memory)之间的带宽可以达到数百 GB/s,比如 P40 的显存带宽为 346GB/s,远远大于 CPU 的内存带宽。但是,相对于 GPU 的计算能力,显存仍然是性能瓶颈的所在。

GPU 与 CPU 之间的数据交互方式

在现代的异构计算系统中,GPU 是以 PCIe 卡作为 CPU 的外部设备存在的,两者之间通过 PCIe 总线通信。对于 PCIe Gen3 x1 理论带宽约为 1000MB/s,所以对于 Gen3 x32 的最大带宽约为 32GB/s,而受限于本身的实现机制,有效带宽往往只有理论值的 2/3,甚至更低。所以,CPU 与 GPU 之间的通信开销是比较大的。
在这里插入图片描述

GPU 的体系结构

在这里插入图片描述

一个 “假想” 的 GPU Core 的结构如下
在这里插入图片描述
一个 GPU Core 包含 8 个 ALU,4 组执行环境(Execution context),每组有 8 个Ctx。这样,一个 Core 可以并发(Concurrent but interleaved)执行 4 条指令流(Instruction Streams),32 个并发程序片元(Fragment)。

一个 “假想” 的 GPU 的结构如下
在这里插入图片描述
则一个 GPU 有 16 个 Core、128 个 ALU,可以同时处理 16 条指令流、64 条并发指令流、32*16 个并发程序片元。

下面以 NVIDIA GeForce GTX 580 为例,看看具体的 GPU Core 的内部架构
在这里插入图片描述
每个 GPU Core 有 64 个 CUDA core,又称 Stream Processor(SP)。每个 CUDA core 可以理解为一个复杂完整的 ALU。这些 CUDA core 分成 2 组,每组 32 个 CUDA core,共享相同的取指/译码部件,这一组称为 Stream Multiprocessor(SM)。每个 Core 可以并发执行 1536 个程序片元,即 1536 个 CUDA threads。一个 GTX 580 GPU 包含 16 个 Core,总共 1024 个 CUDA core,可以并发执行 1536*16 个 CUDA threads.

在这里插入图片描述

GPU 的工作原理

在这里插入图片描述
GPU 的图形(处理)流水线如下:

  • 顶点生成:这阶段 GPU 读取描述 3D 图形外观的顶点数据并根据顶点数据确定 3D 图形的形状及位置关系,建立起 3D 图形的骨架。在支持 DX8 和 DX9 规格的 GPU 中,这些工作由硬件实现的 VertexShader(顶点着色器)完成。
  • 光栅化计算:显示器实际显示的图像是由像素组成的,我们需要将上面生成的图形上的点和线通过一定的算法转换到相应的像素点。把一个矢量图形转换为一系列像素点的过程就称为光栅化。例如:一条数学表示的斜线段,最终被转化成阶梯状的连续像素点。
    在这里插入图片描述
  • 纹理帖图:顶点单元生成的多边形只构成了 3D 物体的轮廓,而纹理映射(Texture Mapping)工作完成对多边形表面的帖图,通俗的说,就是将多边形的表面贴上相应的图片,从而生成 “真实” 的图形。TMU(Texture Mapping Unit)即是用来完成此项工作。
  • 像素处理:这阶段(在对每个像素进行光栅化处理期间)GPU 完成对像素的计算和处理,从而确定每个像素的最终属性。在支持 DX8 和 DX9 规格的 GPU 中,这些工作由硬件实现的 PixelShader(像素着色器)
  • 最终输出:由 ROP(光栅化引擎)最终完成像素的输出,1 帧渲染完毕后,被送到显存帧缓冲区。

在这里插入图片描述

NOTE:因为流水线效率的问题,实际上 GPU 有可能是乱序执行上述工作的。

GPU 的关键参数

  • CUDA 核心:CUDA 核心的数量决定了 GPU 并行处理能力,在深度学习、机器学习等并行计算类业务下,CUDA 核心多意味着性能好一些。

  • 显存容量:其主要功能就是暂时储存 GPU 要处理的数据和处理完毕的数据。显存容量大小决定了 GPU 能够加载的数据量大小。在显存已经可以满足客户业务的情况下,提升显存不会对业务性能带来大的提升。在深度学习、机器学习的训练场景,显存的大小决定了一次能够加载训练数据的量,在大规模训练时,显存会显得比较重要。

  • 显存位宽:显存在一个时钟周期内所能传送数据的位数,位数越大则瞬间所能传输的数据量越大,这是显存的重要参数之一。

  • 显存频率:一定程度上反应着该显存的速度,以 MHz(兆赫兹)为单位,显存频率随着显存的类型、性能的不同而不同。显存频率和位宽决定显存带宽。

  • 显存带宽:指显示芯片与显存之间的数据传输速率,它以字节/秒为单位。显存带宽是决定显卡性能和速度最重要的因素之一。

  • 其他指标:除了显卡通用指标外,NVIDIA 还有一些针对特定场景优化的指标,例如 TsnsoCore、RTCoreRT 等能力。例如 TensenCore 专门用于加速深度学习中的张量运算。

CUDA 编程模型

CUDA(Compute Unified Device Architecture,统一计算架构)是由 NVIDIA 所推出的一种集成技术,是对于 GPGPU 的正式名称,本质是一种外部接口编程模型。利用 CUDA 技术,使 GPU 能够解决复杂的计算问题。它包含了 CUDA 指令集架构(ISA)以及 GPU 内部的并行计算引擎。开发人员现在可以使用 C 语言来为 CUDA 架构编写程序。CUDA 配合适当的软件(e.g. MediaCoder、Freemake Video Converter)就可以利用 GPU 进行高清视频编码加速。视频解码方面亦然。简而言之,CUDA 是获取 NVIDIA GPU 运算能力的开发平台。所有基于 G80 及之后架构的民用与专业显卡或运算模块皆支持 CUDA 技术。

GPU 可以利用多个 CUDA 核心来做并行计算,而 CPU 只能按照顺序进行串行计算,同样运行 3000 次的简单运算,CPU 需要 3000 个时钟周期,而配有 3000 个 CUDA 核心的 GPU 运行只需要 1 个时钟周期。

在 GPUs(GPGPU)上使用图形 APIs 进行传统通用计算,CUDA 技术有下列几个优点:

  • 分散读取:代码可以从存储器的任意地址读取
  • 统一虚拟内存
  • 共享存储器:CUDA 公开一个快速的共享存储区域(每个处理器 48K),使之在多个进程之间共享。其作为一个用户管理的高速缓存,比使用纹理查找可以得到更大的有效带宽。
  • 与 GPU 之间更快的下载与回读。
  • 全面支持整型与位操作,包括整型纹理查找。

CUDA 的架构

在这里插入图片描述
CUDA 主要提供了 4 个重要的组件:CUDA C 和对应的 COMPILER(编译器),CUDA 库、CUDA RUNTIME 和 CUDA DRIVER。

  • CUDA C:其实就是标准 C 的变种,它加入 4 大特性:
    • 可以定义程序的哪部分运行在 GPU 或 CPU 上;
    • 可以定义变量位于 GPU 的存储类型;
    • 利用 KERNEL、BLOCK、GRID 来定义最原始的并行计算;
    • State 变量。
  • CUDA 开发库:基于 CUDA 技术所提供的应用开发库。CUDA 的 1.1 版提供了两个标准的数学运算库:CUFFT(离散快速傅立叶变换)和 CUBLAS(离散基本线性计算)的实现。这两个数学运算库所解决的是典型的大规模的并行计算问题,也是在密集数据计算中非常常见的计算类型。开发人员在开发库的基础上可以快速、方便的建立起自己的计算应用。此外,开发人员也可以在 CUDA 的技术基础上实现出更多的开发库。
  • CUDA 运行时环境:提供了应用开发接口和运行期组件,包括基本数据类型的定义和各类计算、类型转换、内存管理、设备访问和执行调度等函数。基于 CUDA 开发的程序代码在实际执行中分为两种,一种是运行在 CPU 上的宿主代码(Host Code),一种是运行在 GPU 上的设备代码(Device Code)。不同类型的代码由于其运行的物理位置不同,能够访问到的资源不同,因此对应的运行期组件也分为公共组件、宿主组件和设备组件三个部分,基本上囊括了所有在 GPGPU 开发中所需要的功能和能够使用到的资源接口,开发人员可以通过运行期环境的编程接口实现各种类型的计算。
  • CUDA 驱动:由于目前存在着多种 GPU 版本的 NVIDIA 显卡,不同版本的 GPU 之间都有不同的差异,因此 CUDA 驱动基本上可以理解为是 CUDA-enable 的 GPU 的设备抽象层,提供硬件设备的抽象访问接口。CUDA 提供运行期环境也是通过这一层来实现各种功能的。由于体系结构中硬件抽象层的存在,CUDA 今后也有可能发展成为一个通用的 GPU 标准接口,兼容不同厂商的 GPU 产品。

对于软件开发者来说,使用 CUDA 平台调用 CUDA 的加速库使用的语言包括:C、C++ 和 Fortran。C/C++ 编程者使用 UDAC/C++ 并用 nvcc 进行编译。Nvidia 的 LLVM 库是基于 C/C++ 编译器的。Fortran 的开发者能够使用 CUDA Fortran,编译使用 PGI CUDA Fortran。当然 CUDA 平台也支持其他的编程接口,包括 OpenCL,微软的 DirectCompute、OpenGL ComputeShaders 和 C++ AMP。第三方的开发者也可以使用 Python、Perl、Fortran、Java、Ruby、Lua、Haskell、R、MATLAB、IDL 由曼赛马提亚原生支持。

CUDA 的核心概念

再次小结 CUDA 的心和概念:

SP(Streaming Processor):是最基本的处理单元,指令和任务最终都是在 SP 上处理的。GPU 进行并行计算,也就是很多个 SP 同时做处理。
SM(Streaming Multi-Processor):多个 SP 加上其他的一些资源组成了一个 SM,其他资源也就是存储资源,共享内存,寄储器等。
Warp:GPU 执行程序时的调度单位,目前 CUDA 的 Warp 大小为 32,同在一个 Warp 的线程,以不同数据资源执行相同的指令。
GRID、Block、Thread:利用 CUDA 进行编程时,一个 GRID 分为多个 Block,而一个 Block 可分为多个 Thread。

  • SM 与 SP 的关系
    在这里插入图片描述

  • GRID、Blouk 与 Thread 的关系
    在这里插入图片描述

    • 每个 Block 所能包含的 Thread 数量是有限制的,因为目前每个 Block 内的所有 Threads 都是在一个物理的处理器核中,并且共享了这个核有限的内存资源。当前的 GPU 中,每个 Block 最多能执行 1024 个 Thread。
    • 多个 Blocks 可以组成 1 维、2 维或者 3 维的 Grid。kernel 函数可以访问 Grid 内部标识 Block 的内置变量 BlockIDX,也可以访问表示 Block 维度的内置变量 BlockDim。
  • Warp 调度单元与 Threads 的关系
    在这里插入图片描述

上图反映了 Warp 作为调度单位的作用,每次 GPU 调度一个 Warp 里的 32 个线程执行同一条指令,其中各个线程对应的数据资源不同。
在这里插入图片描述
上图反映了 Warp 是如何排程的,即最终将 CUDA thread 映射到实际的物理硬件计算单元中执行(Thread -> SP Block -> SM Grid -> GPU)。一个 SM 只会执行一个 Block 里的 Warp,当该 Block 里 Warp 执行完后才会执行其他 Block 里的 Warp。进行划分时,最好保证每个 Block 里的 Warp 数量合理,那样一个 SM 可以交替执行里面的 Warp,从而提高效率。此外,在分配 Block 时,要根据 GPU 的 SM 个数,分配出合理的 Block 数,让 GPU 的 SM 都利用起来,提利用率。分配时,也要考虑到同一个线程 Block 的资源问题,不要出现对应的资源不够。

CUDA threads 在执行时,可以访问多个 Memory Spaces,每个线程有自己的私有的 Local Memory。每个 Block 有一个 Shared Memory,Block 的所有线程都可以访问。最后,所有线程都可以访问 Global Memory。不同的内存访问速度为:本地内存 > 共享内存 > 全局内存。通过 cudaMalloc 分配的内存就是全局内存。核函数中用 __shared__ 修饰的变量就是共享内存。 核函数定义的变量使用的就是本地内存。

在这里插入图片描述

CUDA 的工作原理

在这里插入图片描述

GPU 是协处理器,与 CPU 端存储是分离的,故 GPU 运算时必须先将 CPU 端的代码和数据传输到 GPU,GPU 才能执行 kernel 函数。在 CUDA 中,程序的执行区域分为两部分,CPU(HOST)和 GPU(DEVICE),任务组织和发送是在 CPU 里完成的,而并行计算是在 GPU 里完成。每当 CPU 遇到需要并行计算的任务,则将要做的运算组织成 kernel,然后丢给 GPU 去执行。当然任务是通过 CUDA 系统来丢的,CUDA 在把任务正式提交给 GPU 前,会对 kernel 做些处理,让 kernel 符合 GPU 体系架构。

假设,我们先简单的把 GPU 当作拥有上百个核的 CPU,kernel 当成一个要创建为线程的函数。所以,CUDA 现在就要将你的 kernel 创建出上百个 thread,然后将这些 thread 送到 GPU 中的各个核上去运行,但为了更好的利用 GPU 资源,提高并行度,CUDA 还要将这些 thread 加以优化组织,将能利用共有资源的线程组织到一个 thread block 中,同一 thread block 中的 thread 可以通过 share memory 共享数据,每个 thread block 最高可拥有 512 个线程。拥有同样维度同样 kernel 的 thread block 被组织成一个 grid,而 CUDA 处理任务的最大单元便是 grid 了。

云主机显卡的实现方式

目前在虚拟机中使用图形处理的方式有三种:

  1. 采用虚拟显卡
  2. 采用物理显卡直通
  3. 采用物理显卡虚拟化

虚拟显卡

虚拟显卡技术,主要用于虚拟机 Remote Console 领域,如:VNC(Virtual Network Computing,虚拟网络计算机),它能将完整的窗口界面通过网络,传输到另一台计算机的屏幕上。VNC 主要由 VNC server 和 VNC viewer 两部分组成。用户需先将 VNC server 安装在被远程操控的计算机上,然后才能在客户端执行 VNC viewer 进行远程操控。但 VNC 仍未能提供硬件图形加速能力,这些虚拟显示设备都是通过使用 CPU 以及内存的方式来对图形数据进行处理的,并没有应用到物理显示设备的功能。而 **VMGL(VMM-Independent Graphics Acceleration)**解决了这个问题。VMGL 是一个独立于 Hypervisor 的图形加速系统,采用了前端虚拟化(Front-end virtualization)机制将需要图形处理的数据发送到一个拥有硬件图形加速功能的 VMM 上进行相应的图形数据处理。

物理显卡直通

显卡直通,或称显卡穿透,即 GPU 直通,是指绕过 Hypervisor 将服务器的 GPU 硬件外设以直通(Pass-Through)的方式分配给某个虚拟机的技术,并通过远程协议使得用户可以进行远程接入。相对的,只有该虚拟机拥有使用 GPU 的权限。用户可以通过终端远程接入到虚拟机,这样虚拟机就可以使用 GPU 获得 3D 加速能力。这种独占设备的分配方式保持了 GPU 的完整性和独立性,在性能方面与非虚拟化条件下非常接近,且可以用来进行通用计算。此外,显卡直通方式还具有兼容性好、对 GPU 厂商无依赖等优势。但是显卡直通技术需要利用显卡的一些特殊细节,只能被一个虚拟机独占,且兼容性差,仅在部分 GPU 中设备可以使用。

在科学计算大多数领域中都可以使用 GPU 加速,包括化学研究,流体动力学分析,结构分析,环境建模,地球物理学,可视化/图像处理。在科学计算领域,要求极强的双精度计算能力。在模拟仿真过程中,消耗大量计算资源的同时,会产生大量临时数据,对存储带宽与时延也有极高的要求,这些场景通常采用 GPU 直通技术。

一般情况下,将 PCI 设备提供到虚拟机需要经过 Hypervisor 的模拟,PCI 设备首先经过 Host OS 的物理驱动,然后在 Hypervisor(e.g. KVM-QEMU)层将物理驱动模拟成模拟驱动并提供给虚拟机。
在这里插入图片描述
而 GPU Pass-Through 技术则可以绕过 Hypervisor,通过将 Host 上 GPU 设备的 PCI 内存地址映射给云主机,将 GPU 设备直接加载给云主机进行使用,虚拟机看到的该设备,就完全是一块物理卡。
在这里插入图片描述

Xen 4.0 增加了 VGA Passthrough 技术,利用了英特尔设备虚拟化(Intel VT-d)技术将显卡设备暴露给某个客户虚拟机,不仅其它客户虚拟机不能访问,就连宿主虚拟机也失去了使用该 GPU 的权限。它在客户虚拟机中实现了显卡的一些特殊细节,如:VGA BIOS、文本模式、IO 端口、内存映射、VESA 模式等,以支持直接访问。Xen Server VGA Pass-Through 技术的 GPU 执行效率高,功能全,但只能被单一虚拟机占用,失去了设备复用的功能。

VMware ESXi 提供了一个 VM DirectPath I/O 框架,使用该技术也可以将显卡设备穿透给某个虚拟机使用。XenServer 和 ESXi 使用的是不同的技术但是最终效果都是一样的,即将物理显卡设备直通给某个虚拟机使用,以达到虚拟机进行 3D 显示和渲染的效果。

由于显卡直通实际上是由 GuestOS 使用原生的驱动和硬件,缺少必要的中间层来跟踪和维护 GPU 状态,它不支持实时迁移等虚拟机高级特性。如:Xen Server VGA Pass-Through 禁止虚拟机执行 Save、Restore、Migration 等操作。VMware 虚拟机亦然,一旦开启 VM DirectPath I/O 功能,虚拟机就失去了执行挂起/恢复、实时迁移的能力。

物理显卡虚拟化

GPU 虚拟化与 CPU 虚拟化类似,核心是切片轮询,将这些显卡时间片分配给虚拟机使用。支持 GPU 虚拟化的显卡一般可以根据需要切分成不同的规格的时间片,并分配给多台虚拟机使用。目前市场上的 GPU 厂商分别有 NVIDIA 和 AMD,两者各自有自己提出的 vGPU 技术方案。

NIVDIA vGPU 的设计主要实现了 Mediated Passthrough(分片透传)。Mediated Passthrough 是一种完全软件定义的 GPU 虚拟化解决方案,其技术原理主要为:对于与 GPU 性能相关的访问直接透传给云主机,把与性能无关功能的相关访问在 Mdev 模块中来模拟实现。Mdev 是此方案的关键技术,简单解释一下,Mdev 即 mediated 设备框架,能够驱动 VFIO 框架及接口支持虚拟 PCI 设备,因此也就能够完全基于软件实现,将宿主机上的物理 GPU 切分成为多个虚拟 GPU 设备并进行共享。

在这里插入图片描述

相对的,AMD 的 vGPU 实现则遵循了 SR-IOV 规范,这个规范定义了以标准化的方式支持实现多个云主机共享一个 PCI 设备。可理解为一个 PCI 设备在物理层面上被切分为多个,并且每个都是符合 PCI 标准的 PCI 设备。而由于这个能力,切分后的每个单元都可以再通过 PCI 透传(Pass-Through)的方式分别提供给多个云主机使用。GPU 作为一种典型 PCI 设备,自然也支持以上技术的实现,AMD vGPU 方案就是如此。

在这里插入图片描述

KVM 虚拟机通过 PCI Pass-through 使用 NVIDIA 显卡

等拿到卡了再做补充。