float16数据类型是否可以在计算超越函数时节省计算周期?



很明显,float16可以节省带宽,但float16可以节省计算周期,而计算超越函数,如exp()?

如果您的硬件完全支持它,而不仅仅是转换为float32,那么是肯定的。例如,在GPU上,或在启用AVX-512的Intel Alder Lake上,或在Sapphire Rapids上。Intel芯片上的半精度浮点运算。或者在Apple M2的cpu上。

如果你可以在一个核心上每个时钟做两个64字节的fma SIMD向量,如果每个向量32个半精度fma而不是16个单精度fma,你的速度是两倍。


速度与精度的权衡:只需要满足FP16

如果FP16没有硬件ALU支持,只是不需要那么高的精度因为你知道你最终会四舍五入到fp16。因此,即使您使用float32计算,也可以使用较低次的多项式近似值,从而减少FMA操作。

顺便说一句,explog对于浮点来说很有趣,因为格式本身是围绕指数表示构建的。所以你可以通过转换fp->int并将该整数填充到fp位模式的指数字段中来实现指数。然后对于FP数的小数部分,使用多项式近似来得到指数的尾数。log的实现是相反的:提取指数域,并使用尾数的对数的多项式近似,在1.0到2.0的范围内。

  • log2(__m256d)在AVX2中的高效实现

  • 使用AVX实现指数函数的最快速度

  • 非常快的近似对数(自然对数)函数在c++ ?

  • vgetmantps vs andpd获取float尾数的指令

通常您确实需要一些FP操作,因此我认为不值得尝试仅使用16位整数操作来避免解包为float32,即使对于exp或log,这与浮点数的significand * 2^exponent格式有些特殊且密切相关,不像sin/cos/tan或其他超越函数。

所以我认为你最好的选择通常仍然是将fp16转换为fp32,如果你没有AVX-512这样的指令,fp16可以在它上面做实际的FP数学。但是,您可以通过不需要那么高的精度来获得性能,因为实现这些函数通常涉及速度与精度的权衡。

最新更新