根据documentation,fma()
中有math.h
个功能。这非常好,我知道FMA如何工作以及如何使用它。但是,我不太确定这在实践中如何实施?我最感兴趣的是x86
和x86_64
架构。
是否存在FMA的浮点(非向量)指令,可能是IEEE-754 2008所定义的?
是否使用了FMA3或FMA4指令?
当依赖精度时,是否存在确保使用真实FMA的内在因素?
答案 0 :(得分:7)
实际实施因平台而异,但讲得非常广泛:
如果您告诉编译器使用硬件FMA指令(PowerPC,带有VFPv4或AArch64,Intel Haswell或AMD Bulldozer及其后的ARM)定位计算机,编译器可能会替换fma( )
只需将适当的指令放入代码即可。这不是保证,但通常是良好的做法。否则,您将调用数学库,并且:
在具有硬件FMA的处理器上运行时,应使用这些指令来实现该功能。但是,如果您的操作系统版本较旧,或者数学库版本较旧,则可能无法使用这些说明。
如果您在没有硬件FMA的处理器上运行,或者您使用的是较旧的(或者不是很好的)数学库,那么将使用FMA的软件实现。这可以使用巧妙的扩展精度浮点技巧或整数运算来实现。
fma( )
函数的结果应始终正确舍入(即“真正的fma”)。如果不是,那就是系统数学库中的错误。不幸的是,fma( )
是正确实现的更难的数学库函数之一,因此许多实现都有错误。请将它们报告给您的图书馆供应商,以便它们得到修复!
当依赖精度时,是否存在确保使用真实FMA的内在因素?
鉴于良好的编译器,这不应该是必要的;它应该足以使用fma( )
函数并告诉编译器您要定位的架构。但是,编译器并不完美,因此您可能需要在x86上使用_mm_fmadd_sd( )
和相关的内在函数(但是将错误报告给编译器供应商!)
答案 1 :(得分:2)
因此,虽然Dekker的两个产品可以通过硬件FMA大大加速,但Dekker的两个产品的错误项计算不一个强大的FMA实现。
正确的实现需要使用高于双精度的求和算法,或者以递减的数量级添加术语。