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

目录

显卡

显卡(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(GeForce 256)绘图处理芯片时首先提出的概念,而对手冶天科技(ATi,已被 AMD 收购)亦提出视觉处理器(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 图形处理器

CPU 与 GPU 的区别

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 图形处理器
  • GPU 抽象架构
    计算机组成原理 — GPU 图形处理器

GPU 的架构

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

CUDA 编程模式

CUDA(Compute Unified Device Architecture,统一计算架构)是由 NVIDIA 所推出的一种集成技术,是对于 GPGPU 的正式名称,本质是一种外部接口编程模型。利用 CUDA 技术,配合适当的软件(e.g. MediaCoder、Freemake Video Converter)就可以利用 GPU 进行高清视频编码加速。视频解码方面亦然。简而言之,CUDA 是获取 NVIDIA GPU 运算能力的开发平台。所有基于 G80 及之后架构的民用与专业显卡或运算模块皆支持 CUDA 技术。

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

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

CUDA 的架构

计算机组成原理 — GPU 图形处理器
CUDA 主要提供了 4 个重要的组件:CUDA C 和对应的 COMPILER(编译器),CUDA 库、CUDA RUNTIME 和 CUDA DRIVER。

  • CUDA C 其实就是标准 C 的变种,它加入 4 大特性:
    • 可以定义程序的哪部分运行在 GPU 或 CPU 上;
    • 可以定义变量位于 GPU 的存储类型;
    • 利用 KERNEL、BLOCK、GRID 来定义最原始的并行计算;
    • State 变量。
  • CUDA 库则包含了很多有用的数学应用,如 cuFFT。
  • CUDA RUNTIME 其实就是个 JIT 编译器,动态的将 PTX 中间代码编译成符合实际平台的硬件代码,并作特定优化。
  • CUDA DRIVER 便是相应 API 与 GPU 打交道的接口了。

利用 CUDA 进行多并发编程的原理

在 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. 采用 GPU 虚拟化

虚拟显卡

虚拟显卡技术,主要用于虚拟机 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 上进行相应的图形数据处理。

显卡直通

显卡直通(Pass-Through),或称显卡穿透,是指绕过 Hypervisor 将 GPU 单独分配给某个虚拟机的技术。相对的,只有该虚拟机拥有使用 GPU 的权限,这种独占设备的分配方式保持了 GPU 的完整性和独立性,在性能方面与非虚拟化条件下非常接近,且可以用来进行通用计算。但是显卡直通技术需要利用显卡的一些特殊细节,只能被一个虚拟机独占,且兼容性差,仅在部分 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 虚拟化的显卡一般可以根据需要切分成不同的规格的时间片,并分配给多台虚拟机使用。

以 NVIDIA 提供的 GPU 虚拟化技术为例,即是 vCUDA(virtual CUDA)技术。vCUDA 采用在用户层拦截和重定向 CUDA API 的方法,在虚拟机中建立物理 GPU 的逻辑映像,即虚拟 GPU。以此实现了 GPU 资源的细粒度划分、重组和再利用,支持多机并发、挂起恢复等虚拟机高级特性。

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

等拿到卡了再做补充。