如何在x86_64上使用gcc启用__fp16类型

17

__fp16浮点数据类型是C标准的一个知名扩展,尤其在ARM处理器上使用。我希望在我的x86_64处理器上运行它们的IEEE版本。虽然我知道它们通常没有这样做,但我可以通过使用“unsigned short”存储来模拟它们(它们具有相同的对齐要求和存储空间),以及(硬件)浮点算术。

在gcc中是否有一种请求方式?

我假设四舍五入可能会略微“不正确”,但对我来说没关系。

如果这也适用于C++,那就太理想了。


1
我认为它没有针对x86目标的这个功能。如果有的话,它会非常慢,因为所有操作都必须在软件仿真中运行,而不是使用FP硬件。你为什么想要这样做呢? - Cody Gray
8
半精度浮点数在相对较新的x86 CPU上(Intel自Ivy Bridge,AMD自Piledriver)得到本地支持(仅作为存储格式,需要转换为单精度才能进行实际计算)。 - user784668
3
好的,他们确实是这样,@Fanael。感谢你指出来。我错过了他们的介绍。因此,您将使用 _mm256_cvtph_ps 作为“加载”(将半精度浮点型转换为单精度浮点型),并使用 _mm256_cvtps_ph 作为“存储”(将单精度浮点型转换为半精度浮点型)。结果证明这是相当快的,并且在内存受限的情况下实际上非常有用。Nonyme,使用类似于平台抽象库的内部函数,实现这一点是否可行?或者您是否坚定地希望编译器隐式生成此代码? - Cody Gray
5
目标是在 x86_64 服务器上运行为 ARM 设计的大型代码库。如果“平台抽象库”不需要修改代码,则可以实现。但我怀疑这是可行的。注意:我设法通过欺骗 Clang 来做到这一点,即通过欺骗语义解析器来定义 __fp16,并在 x86_64 上接受它作为函数参数/返回值。然后它成功使用前述内部函数来进行转换并使用浮点数进行计算。 - Nonyme
2
我编辑了clang源代码,以在X86目标上添加__fp16内置类型(默认情况下仅在ARM上启用)。然后编译器的其余部分自行处理它。 - Nonyme
显示剩余6条评论
4个回答

6

截至gcc 8.2.0版本,我没有找到实现此功能的方法。

至于clang,在6.0.0版本中,以下选项显示出了一定的成功:

clang -cc1 -fnative-half-type -fallow-half-arguments-and-returns

选项-fnative-half-type启用了__fp16类型的使用(而不是升级为float)。虽然选项-fallow-half-arguments-and-returns允许通过值传递__fp16,但API不是标准的,请注意不要混合不同的编译器。
话虽如此,它不提供使用__fp16类型的数学函数(它将将其升级为/从floatdouble)。
对于我的用例来说,这已经足够了。

2
缺少__fp16数学函数是有充分的理由的:x86对半精度的支持仅限于转换为floatvcvtph2ps和反向操作,仅适用于SIMD向量,而不是标量)。因此,它仅在加载和存储时以ALU转换的代价来减少数组的缓存占用。即使转换为double也需要两个步骤。在x86上绝对不要传递__fp16数据寄存器,因为每次计算都必须转换为float然后再转回去。 - Peter Cordes
3
更新:Sapphire Rapids 具有完整的标量和 SIMD 支持 AVX-512 FP16 数学指令,以及一些早期 CPU 中出现的 BF16。Intel 芯片上的半精度浮点运算 - Peter Cordes

3

C++23 introduces std::float16_t

#include <stdfloat> // C++23
 
int main()
{
    std::float16_t f = 0.1F16;
}

请注意,这是一个可选类型,完全不需要。 - undefined

2

_Float16是您现在应该在最新版本的clang和gcc中寻找的类型。

至少在我使用过的编译器中,__fp16是一种有限的类型,您只能将其转换为/从binary32(在支持硬件的情况下)而_Float16更像是一个“真正”的算术类型,尽管在如此有限的精度下不应尝试太多。


2
@Nonyme的解决方案存在问题,使用clang -cc1会使你失去clang驱动程序提供的所有隐式参数(特别是系统头文件的隐式包含路径)。 更好的解决方案是通过clang驱动程序的-Xclang参数将与__fp16相关的标志传递给cc1,如下所示:
clang input.c -Xclang -fnative-half-type -fallow-half-arguments-and-returns

我应该补充一点,@Nonyme的--fallow-half-arguments-and-returns在我的clang版本上没有起作用。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接