主要内容

什么是半精度?

IEEE® 754 半精度浮点格式是一个 16 位字,进一步分为包含 1 位的符号指示符 s,包含 5 位的偏置指数 e 和包含 10 位的小数 f

Schematic showing bit allocation for half-precision data type.

由于 half 类型的数值使用 16 位来存储,因此它们比 single 类型(使用 32 位)的数值或 double 类型(使用 64 位)的数值需要更少的内存。但是,由于存储它们所用的位数较少,half 类型的数值所表示的精度低于 singledouble 类型的数值。

下表给出了支持的浮点数据类型的范围、偏置和精度。

数据类型

下限

上限

指数偏置

精度

半精度

2−14 ≈ 6.1·10−5

(2−2-10) ·215≈ 6.5·104

15

2−10 ≈ 10−3

单精度

2−126 ≈ 10−38

2128 ≈ 3 · 1038

127

2−23 ≈ 10−7

双精度

2−1022 ≈ 2 · 10−308

21024 ≈ 2 · 10308

1023

2−52 ≈ 10−16

有关半精度数据类型的视频介绍,请参阅什么是半精度?以及建模和代码生成中的半精度数学

半精度应用

当算法包含较大或未知的动态范围(例如反馈环中的积分器)时,或当算法使用难以采用定点设计的运算(例如 atan2)时,使用浮点表示可能是有利的。半精度数据类型仅占用 16 位内存,但其浮点表示使其能够处理比相同大小的整数或定点数据类型更宽的动态范围。这使得半精度特别适合一些图像处理和图形应用。当半精度用于深度神经网络时,可以减少训练和推断所需的时间。对查找表的存储时间使用半精度类型,可以减少查找表的内存占用量。

MATLAB 示例

  • Fog Rectification (GPU Coder) - 去雾图像处理算法使用卷积、图像颜色空间转换和基于直方图的对比度拉伸来增强输入图像。此示例说明如何生成和执行 CUDA® MEX,其中对这些图像处理操作使用了半精度数据类型。

    Image of a road before and after applying fog rectification algorithm.

  • Edge Detection with Sobel Method in Half-Precision (GPU Coder) - 索贝尔边缘检测算法接受一个输入图像并返回一个输出图像,后者强调与输入图像中的边缘对应的高空间频率区域。此示例说明如何生成和执行 CUDA MEX,其中对输入图像和索贝尔算子核值使用了半精度数据类型。

    Image of peppers before and after applying Sobel edge detection algorithm.

  • 为使用半精度数据类型的索贝尔边缘检测生成代码 (MATLAB Coder) - 此示例说明如何从 MATLAB® 函数生成独立的 C++ 库,该库通过使用半精度浮点数执行图像的索贝尔边缘检测。

Simulink 示例

在嵌入式应用中使用半精度的好处

与其他浮点类型(如单精度和双精度)相比,半精度数据类型使用的内存更少。尽管它仅占用 16 位内存,但其浮点表示使其能够处理比相同大小的整数或定点数据类型更宽的动态范围。

FPGA

当在硬件上使用时,与单精度数据类型相比,半精度数据类型使用的面积小得多,延迟也更低。半精度对于低动态范围应用来说尤其有利。

下图显示了在 Xilinx® Virtex® 7 硬件中使用半精度实现磁场定向控制算法的优势。

Comparison of Fmax, DSPs, LUTs, and Slices for single vs half precision.

GPU

在支持半精度数据类型的 GPU 中,与单精度或双精度相比,算术运算速度更快。

在像深度学习这样需要大量计算的应用中,使用半精度可以在精度没有显著损失的情况下提供显著的性能优势。使用 GPU Coder™,您可以从 Deep Learning Toolbox™ 中生成用于预测各种经过训练的深度学习网络的优化代码。您可以配置代码生成器,以利用适用于 NVIDIA® GPU 的 NVIDIA TensorRT 高性能推理库。TensorRT 通过结合网络层和优化核选择,改进了延迟、吞吐量和内存效率。您还可以配置代码生成器,以利用 TensorRT 的精度模式(FP32、FP16 或 INT8)来进一步提高性能并降低内存需求。

CPU

在支持半精度数据类型的 CPU 中,与单精度或双精度相比,算术运算速度更快。对于原生支持半精度数据类型的 ARM® 目标,您可以从 MATLAB 或 Simulink® 生成原生半精度 C 代码。请参阅使用半精度的代码生成

MATLAB 中的半精度

MATLAB 中的许多函数支持半精度数据类型。有关支持的函数的完整列表,请参阅 half

Simulink 中的半精度

Simulink 中的信号和模块输出可以指定半精度数据类型。参数和部分模块的仿真和代码生成支持半精度数据类型。要查看支持半精度的模块,请在命令行中键入:

showblockdatatypetable

支持半精度的模块在标签为 Half 的列中显示 X。有关 Simulink 中半精度支持的详细信息,请参阅 The Half-Precision Data Type in Simulink

使用半精度的代码生成

C/C++ 代码生成、CUDA 使用 GPU Coder 的代码生成以及使用 HDL Coder™ 的 HDL 代码生成支持半精度数据类型。对于 GPU 目标,半精度数据类型使用 NVIDIA GPU 中支持的原生半精度数据类型以获得最优性能。

有关 MATLAB 和 Simulink 中对半精度代码生成的支持的详细信息,请参阅Half Precision Code Generation SupportThe Half-Precision Data Type in Simulink

对于原生支持半精度特殊类型(如适用于 ARM 编译器的 _Float16_fp16 数据类型)的嵌入式硬件目标,您可以使用 Embedded Coder®MATLAB Coder™ 生成原生半精度 C 代码。有关详细信息,请参阅Generate Native Half-Precision C Code from Simulink ModelsGenerate Native Half-Precision C Code Using MATLAB Coder

另请参阅

| | |

主题