概述
推理加速除了对模型进行处理,例如模型变小,计算量变小以外,还可以在gpu上针对gpu的计算进行并行和去重。
TensorRT是NVIDIA 推出的一款基于CUDA和cudnn的神经网络推断加速引擎,相比于一般的深度学习框架,在CPU或者GPU模式下其可提供10X乃至100X的加速,极大提高了深度学习模型的推断速度。
tensorrt的加速原理一个是支持INT8和FP16的计算,通过在减少计算量和保持精度之间达到一个理想的trade-off,另外一个是TensorRT对于网络结构进行了重构和优化,减少了不必要的计算和重复的计算。包括消除无用输出层、网络的垂直整合、网络的水平组合等方案。
gpu架构设计
1.GPU 架构的基础知识
通过上图可以深入了解 GPU 的核心要素:
- 全局内存 - 存储数据和访问它的程序的外部内存是 GPU 编程的巨大瓶颈和限制
- 计算核心 - 在不同线程中并行执行内核代码的主要计算单元
- 分层缓存 - 缓存可最大限度地减少全局内存访问
- 内存控制器 - 处理对全局内存的限制请求
- 调度程序——GPU的主要控制单元,将线程分配给可用资源执行
然后在每个计算核心中,我了解了主要单元: - 寄存器 - 为每个线程存储数据的专用空间
- 本地/共享内存 - 线程之间共享内存以相互传递数据
- 加载-存储单元 (LSU) - 用于从全局内存存储/加载数据
- 计算单元 - ALU、SFU、专用图形硬件等,用于对寄存器值执行计算
- 调度程序 - 管理每个核心中的资源,并计划何时执行来自不同线程的指令 - GPU 的大部分复杂性都在这里
- Fetcher - 从程序存储器中检索指令
- 解码器——将指令解码为控制信号
2.GPU架构实现
经过多次迭代, GPU 架构的最简化实现:
- 并行化 - SIMD 模式如何在硬件中实现?
- 内存访问 - GPU 如何应对从缓慢且带宽有限的内存访问大量数据的挑战?
- 资源管理 - GPU 如何最大限度地提高资源利用率和效率?
3.编写GPU自定义汇编语言
GPU 可以执行使用 SIMD 编程模式编写的内核。为了实现这一点,必须为 GPU 设计自己的指令集架构 (ISA),这样可以用它来编写内核。
为了实现这一点,制作小型 11 指令 ISA,以允许编写一些简单的矩阵数学内核作为概念证明:
- NOP - 经典的空行(Classic empty row instruction )指令只是为了增加(increment) PC
- BRnzp - 使用 NZP 寄存器的分支指令来启用条件语句和循环
- CMP - 设置 NZP 寄存器以供 BRnzp 指令稍后使用的比较指令
- ADD、SUB、DIV、MUL - 基本算术指令可实现简单的张量计算
- STR/LDR - 在全局数据存储器中存储/加载数据以访问初始数据并存储结果
- CONST - 将常量值加载到寄存器中以方便使用
- RET - 表示线程已完成执行
下面是 ISA 的完整表格,包括每条指令的确切结构:
4.使用 ISA 编写矩阵数学内核
- 现在有了ISA,创建 2 个矩阵数学内核来运行在我的 GPU 上
- 每个内核都指定要操作的矩阵、要启动的线程数以及要在每个线程中执行的代码
-
矩阵加法内核使用 8 个线程添加了两个 1x8 矩阵,并演示了 SIMD 模式的使用、一些基本的算术指令和加载/存储功能
矩阵乘法内核使用 4 个线程将两个 2x2 矩阵相乘,并额外演示了分支和循环
演示矩阵数学功能至关重要,因为图形和机器学习中的现代 GPU 用例的基础在很大程度上围绕着矩阵计算(授予更复杂的内核)。
以下是我为矩阵加法和乘法编写的内核