__fp16
浮点数据类型是C标准的一个知名扩展,尤其在ARM处理器上使用。我希望在我的x86_64处理器上运行它们的IEEE版本。虽然我知道它们通常没有这样做,但我可以通过使用“unsigned short”存储来模拟它们(它们具有相同的对齐要求和存储空间),以及(硬件)浮点算术。
在gcc中是否有一种请求方式?
我假设四舍五入可能会略微“不正确”,但对我来说没关系。
如果这也适用于C++,那就太理想了。
__fp16
浮点数据类型是C标准的一个知名扩展,尤其在ARM处理器上使用。我希望在我的x86_64处理器上运行它们的IEEE版本。虽然我知道它们通常没有这样做,但我可以通过使用“unsigned short”存储来模拟它们(它们具有相同的对齐要求和存储空间),以及(硬件)浮点算术。
在gcc中是否有一种请求方式?
我假设四舍五入可能会略微“不正确”,但对我来说没关系。
如果这也适用于C++,那就太理想了。
截至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
类型的数学函数(它将将其升级为/从float
或double
)。__fp16
数学函数是有充分的理由的:x86对半精度的支持仅限于转换为float
(vcvtph2ps
和反向操作,仅适用于SIMD向量,而不是标量)。因此,它仅在加载和存储时以ALU转换的代价来减少数组的缓存占用。即使转换为double
也需要两个步骤。在x86上绝对不要传递__fp16
数据寄存器,因为每次计算都必须转换为float然后再转回去。 - Peter CordesC++23 introduces std::float16_t
#include <stdfloat> // C++23
int main()
{
std::float16_t f = 0.1F16;
}
_Float16是您现在应该在最新版本的clang和gcc中寻找的类型。
至少在我使用过的编译器中,__fp16是一种有限的类型,您只能将其转换为/从binary32(在支持硬件的情况下)而_Float16更像是一个“真正”的算术类型,尽管在如此有限的精度下不应尝试太多。
clang input.c -Xclang -fnative-half-type -fallow-half-arguments-and-returns
--fallow-half-arguments-and-returns
在我的clang版本上没有起作用。 - undefined
_mm256_cvtph_ps
作为“加载”(将半精度浮点型转换为单精度浮点型),并使用_mm256_cvtps_ph
作为“存储”(将单精度浮点型转换为半精度浮点型)。结果证明这是相当快的,并且在内存受限的情况下实际上非常有用。Nonyme,使用类似于平台抽象库的内部函数,实现这一点是否可行?或者您是否坚定地希望编译器隐式生成此代码? - Cody Gray