如何检测跨平台浮点行为的差异

How to detect differences in floating point behaviour across platforms

本文关键字:跨平台 何检测 检测      更新时间:2023-10-16

我可以执行哪些检查来确定它们在两个硬件平台的浮点行为中存在哪些差异?

验证IEE-754合规性或检查已知错误可能就足够了(以解释我观察到的输出差异)。

我已经通过/proc/cpu 查看了 CPU 标志,两者都声称支持 SSE2 我看了看:

  • https://www.vinc17.net/research/fptest.en.html
  • http://www.jhauser.us/arithmetic/TestFloat.html

但它们看起来很难使用。 我已经构建了TestFloat,但我不确定如何处理它。主页上写着:

"不幸的是,TestFloat的输出不容易解释。详细 使用TestFloat需要IEEE标准的知识 负责任地。

理想情况下,我只需要一个或两个程序或一些简单的配置样式检查,我可以运行并比较两个平台之间的输出。

理想情况下,我会将其转换为配置检查,以确保 尝试在行为异常的平台上编译非可移植代码,它在配置时而不是运行时检测到。

背景

我发现C++应用程序在两个不同平台上的行为存在差异:

  • 英特尔® 至强® CPU E5504
  • 英特尔® 酷睿™ i5-3470 处理器

在两台计算机上本机编译的代码在另一台计算机上运行,但 对于一个测试,行为取决于代码在哪台机器上运行。

澄清在计算机 A 上编译的可执行文件在复制到计算机 B 上运行时的行为类似于在计算机 B 上编译的可执行文件,反之亦然。

它可能是一个未初始化的变量(尽管瓦尔格林德中没有出现任何内容)或许多其他东西,但是 我怀疑原因可能是浮点的不可移植使用。 也许一台机器对浮点组件的解释与另一台机器不同? 实施者已确认他们知道这一点。 这不是我的代码,我不想完全重写它来测试这一点。不过重新编译很好。 我想测试我的假设。

在相关问题中,我正在研究如何启用软件浮点数。这个问题是从另一个角度解决问题的。

更新

我已经沿着配置检查的道路尝试了以下内容,根据@chux的提示。

#include <iostream>
#include <cfloat>
int main(int /*argc*/, const char* /*argv*/[])
{
std::cout << "FLT_EVAL_METHOD=" << FLT_EVAL_METHOD << "n";
std::cout << "FLT_ROUNDS=" << FLT_ROUNDS << "n";
#ifdef __STDC_IEC_559__
std::cout << "__STDC_IEC_559__ is definedn";
#endif
#ifdef __GCC_IEC_559__
std::cout << "__GCC_IEC_559__ is definedn";
#endif
std::cout << "FLT_MIN=" << FLT_MIN << "n";
std::cout << "FLT_MAX=" << FLT_MAX << "n";
std::cout << "FLT_EPSILON=" << FLT_EPSILON << "n";
std::cout << "FLT_RADIX=" << FLT_RADIX << "n";
return 0;
}

在两个平台上给出相同的输出:

./floattest 
FLT_EVAL_METHOD=0
FLT_ROUNDS=1
__STDC_IEC_559__ is defined
FLT_MIN=1.17549e-38
FLT_MAX=3.40282e+38
FLT_EPSILON=1.19209e-07
FLT_RADIX=2

我仍在寻找可能不同的东西。

OP 有 2 个目标有点冲突。

  1. 如何检测跨平台浮点行为的差异 (?

  2. 我只需要一个或两个程序或一些简单的配置样式检查,我可以运行并比较两个平台之间的输出。

是的,有些差异很容易察觉,但有些差异可能非常微妙。
示例 当结果不低于正态时,是否可以设置浮点状态标志FE_UNDERFLOW?

对于一般问题,没有简单的测试。

推荐以下任一:

  1. 修改编码目标以允许名义差异。

  2. 查看是否定义了_STDC_IEC_559__并希望这对您的应用程序来说已经足够了。 考虑到各种其他因素,如FLT_EVAL_METHODFLT_ROUNDS以及优化级别,代码仍然可以合规,但提供不同的结果,但程度将更易于管理。

  3. 如果需要超高一致性,请不要使用浮点。

我发现了一个名为esparanoia的程序,它可以对浮点行为进行一些检查。这是基于威廉·卡汉最初的偏执狂程序发现了臭名昭著的奔腾除法错误。

虽然它没有检测到我的测试系统的任何问题(因此不足以回答这个问题),但其他人可能会感兴趣。