【发布时间】:2019-08-13 11:38:56
【问题描述】:
我可以执行哪些检查来确定两个硬件平台的浮点行为有何不同?
验证 IEE-754 合规性或检查已知错误可能就足够了(解释我观察到的输出差异)。
我通过 /proc/cpu 查看了 CPU 标志,都声称支持 SSE2 我看了看:
但它们看起来很难使用。 我已经构建了 TestFloat,但我不确定如何处理它。主页说:
“很遗憾,TestFloat 的输出并不容易解释。详细 使用 TestFloat 需要了解 IEEE 标准 负责任的。”
理想情况下,我只需要一个或两个程序或一些简单的配置样式检查,我可以运行并比较两个平台之间的输出。
理想情况下,我会将其转换为配置检查,以确保 尝试在行为异常的平台上编译不可移植代码,在配置时而不是运行时检测到。
背景
我发现 C++ 应用程序在两个不同平台上的行为有所不同:
- Intel(R) Xeon(R) CPU E5504
- Intel(R) Core(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
我仍在寻找可能有所不同的东西。
【问题讨论】:
-
验证 IEEE754 合规性不够,因为两个合规的实现可能仍会给出不同的结果。这就是为什么在 TestFloat 上有这样一个警告的原因之一;掌握 IEEE754 非常复杂。
-
我说可能。我的意思是,如果在我的机器上报告了不合规或众所周知的硬件错误,它可能会解释我所看到的行为差异。为了以防万一,我添加了一个说明。
-
这就是我添加评论的原因。您的“验证 IEEE754 合规性可能就足够了”(发现差异)表明您不确定。事实上,您观察到的差异可能是两个兼容的 IEEE754 实现之间的差异。举一个简单的例子,
sin(1.0)的舍入不是由 IEEE754 指定的。 -
我有另一个与此相关的古怪想法,请参阅emulator-to-run-an-application-as-if-its-on-a-different-cpu
-
long double在平台之间的差异比double/float和float的差异更常见于double,因此检查long double特征更有可能发现float的问题。有时可以在检查xxx_TRUE_MIN时发现意外的亚法线。对各种舍入模式的支持有时会有所不同。请参阅 C 规范“B.6 浮动类型的特征”中的 xxx_HAS_SUBNORM和其他内容。不妨都检查一下。
标签: c++ floating-point hardware