如何解决x86_64与ARMv8.2-A之间的浮点计算结果不同
我已经在aarch64和x86_64中编译了相同的Fortran库和代码。它是一个在n维数组/矩阵上运行算法的模型。 ARM CPU是Amazon Graviton2。当代码针对x86_64编译并运行时,AWS中的AMD和Intel选项会产生相同的结果。
我正在使用带有以下标志的gcc / g ++ / gfortran / mpich(所有版本8.3.0,来自debian buster的主要存储库)
-O2 -ftree-vectorize -funroll-loops -w -ffree-form -ffree-line-length-none -fconvert=big-endian -frecord-marker=4
所有代码都可以编译并运行良好,但是,我注意到模型的输出中,结果差异很小。这似乎是精度或舍入问题,因为 大多数 值在输出之间是相同的。但是,在整个输出中都有(看似)随机值,看起来像是为一个圆弧编译的代码被四舍五入或截断了,而另一个圆弧则被四舍五入了。
输出存储为NetCDF(使用NetCDF-Fortran版本4.5.3),并且文件的md5sum在x86_64 CPU之间相同,但在aarch64上不同。
为什么会发生这种情况?还是在编译过程中可以使用的任何标志,以确保跨架构获得相同的结果?
我正在查看的值的精度为5位小数,即123.12345
以下是输出的diff
中的摘录,您可以在其中看到 最 个值相同,但其中一些值四舍五入(我已经用**标记了不同的值:
657c657
< 18.83633,18.83212,18.82778,**18.82337**,18.81886,18.81425,18.80956,---
> 18.83633,**18.82336**,1151c1151
< 17.35448,17.37331,17.39206,17.41071,17.42931,**17.4478**,17.46622,---
> 17.35448,**17.44779**,1711c1711
< 19.77562,19.77532,19.77493,19.77445,19.77386,19.77319,**19.77241**,---
> 19.77562,**19.77242**,2130c2130
< 20.06532,20.06839,**20.07135**,20.07423,20.07702,20.0797,20.0823,---
> 20.06532,**20.07136**,2140c2140
< 20.04788,20.04424,20.04047,**20.03661**,20.03268,20.02863,20.02448,---
> 20.04788,**20.03662**,2600c2600
< 11.54104,11.57732,11.61352,11.6497,11.68579,**11.72186**,11.75784,---
> 11.54104,**11.72185**,
解决方法
如果代码仅使用+,-,*,/和sqrt 之类的基本算术运算,并且编译器处于IEEE754一致性模式下,则无论所使用的CPU是什么,输出应为位相同。 此IEEE754一致性模式通常是默认设置。
否则,该问题可能是由编译器或CPU错误引起的。
诸如-ffast-math
之类的选项将编译器置于非IEEE 754一致性模式。
然后,它使用数学等价规则来优化代码,代码不一定在数值上等效(例如((a*a)*a)*a -> (a*a)*(a*a)
等)。
如果是这种情况,并且编译器对ARM代码的优化不同于x86_64,则可能是一种解释。
此外,如果代码使用诸如sin
,cos
,exp
atan2
之类的函数,则只有在完全相同的运行时,输出才是位相同的,使用时间库。这是因为这些函数未正确舍入,并且结果通常会有微小的错误(可能会在计算中放大并以您观察的方式显示出来)。
对于x86_64,可能还需要使用针对这些功能的特殊CPU指令,对于ARM,则应使用软件实现,反之亦然。请注意,即使在CPU / FPU上实现了这些功能,也无法正确舍入它们,并且很有可能使用了不同的算法。
TL / DR:检查-ffast-math
的编译器标志,或尝试在选项末尾添加-fno-fast-math
。
编辑:如@Rob在评论中所述,可以添加-ffp-contract=off
。在gcc中,默认情况下,即使未明确请求,“ fast”(独立于-ffast-math
)也可能生成FMA指令。这也会破坏754一致性。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。