考虑一下NVIDIA Quadro RTX 8000(规格如下)。使用它来执行单次(32 位精度)的理论性能为 16.31 TFLOPS。如果我们将精度降低到半精度(16 位),理论性能翻倍至 32.62 TFLOPS。但是,如果我们将精度从 32 位减半到 64 位,理论性能下降32 倍至 509.8 GFLOPS。为什么从 FP32 到 FP64 的性能损失比从 FP32 到 FP16 的性能提升要大得多?
我认识到每个 GPU 并非总是如此,但我的印象是,对于许多 GPU,从 FP64 -> FP32 获得的收益远大于从 FP32 -> FP16 获得的收益。
可能是因为单元内的默认寄存器大小是 32 位。
一个 32 位寄存器可以保存两个 16 位值,它们可以相乘,从而使性能翻倍。
另一方面,乘以 64 位值将需要 4 个寄存器(两个 64 位值分别分成 32 位部分)或在执行低 32 位和高 32 位之间的内存加载/存储 64位值。将需要额外的加载/存储和字节来处理可能使用更多寄存器的溢出。在 32 位寄存器中进行 64 位浮点数学运算是可行的,但由于是双倍宽度,它远非简单的减半。涉及到很多额外的数学运算,因为你不能做一个简单的“将这两个寄存器加在一起”,而是必须做很长的数学运算。
来自堆栈溢出将 64 位数乘以 8086 asm 中的 32 位数
矢量处理器的重点在于它们处理指令和数据流,即使在具有大量带宽内存访问的 GPU 中也是昂贵的,尤其是当您的数据依赖于先前的计算部分时。出于偏好,矢量处理器只想要一个“针对这个巨大的数组运行这个简单的代码”的流,并且在一个数据上的大量重复运行很快就会消耗带宽和处理器内核。
有证据表明, “游戏”卡上的FP64 性能由于很少或没有支持 FP64 的单元而受到削弱。结果,您最终只能在 32 位寄存器中“艰难地”进行 64 位数学运算。