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

时间:2019-03-22 13:11:12

标签: c++ floating-point hardware

我可以执行哪些检查来确定它们在两个硬件平台的浮点行为上有什么区别?

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

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

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

  

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

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

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

背景

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

  • 英特尔(R)至强(R)CPU E5504
  • 英特尔(R)酷睿TM i5-3470 CPU

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

说明 在计算机A上编译的可执行文件在复制以在计算机B上运行时的行为与在计算机B上编译的可执行文件的行为相同,反之亦然。

它可能是未初始化的变量(尽管valgrind中未显示任何变量)或许多其他东西,但是 我怀疑原因可能是非便携式使用浮点数。 也许一台机器对浮点组件的解释与另一台机器不同? 实施者已经确认他们知道这一点。 它不是我的代码,我也不想完全重写它来测试它。重新编译是可以的。 我想检验一下我的假设。

related question中,我正在研究如何启用软件浮点。这个问题从另一方面解决了这个问题。

更新

我已经沿着@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 defined\n";
#endif
#ifdef __GCC_IEC_559__
   std::cout << "__GCC_IEC_559__ is defined\n";
#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

我还在寻找可能与众不同的东西。

2 个答案:

答案 0 :(得分:0)

OP的2个目标有些冲突。

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

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

是的,有些差异很容易检测,但是有些差异可能非常微妙。
 样本Can the floating-point status flag FE_UNDERFLOW set when the result is not sub-normal?

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

推荐之一:

  1. 重新定义编码目标以允许名义差异。

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

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

答案 1 :(得分:0)

我找到了一个名为esparanoia的程序,该程序对浮点行为进行了一些检查。这是基于William Kahan's原始的偏执程序,该程序发现了臭名昭著的奔腾分裂漏洞。

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