如何检测跨平台浮点行为的差异
How to detect differences in floating point behaviour across platforms
我可以执行哪些检查来确定它们在两个硬件平台的浮点行为中存在哪些差异?
验证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 个目标有点冲突。
-
如何检测跨平台浮点行为的差异 (?
-
我只需要一个或两个程序或一些简单的配置样式检查,我可以运行并比较两个平台之间的输出。
是的,有些差异很容易察觉,但有些差异可能非常微妙。
示例 当结果不低于正态时,是否可以设置浮点状态标志FE_UNDERFLOW?
对于一般问题,没有简单的测试。
推荐以下任一:
修改编码目标以允许名义差异。
查看是否定义了
_STDC_IEC_559__
并希望这对您的应用程序来说已经足够了。 考虑到各种其他因素,如FLT_EVAL_METHOD
和FLT_ROUNDS
以及优化级别,代码仍然可以合规,但提供不同的结果,但程度将更易于管理。如果需要超高一致性,请不要使用浮点。
我发现了一个名为esparanoia的程序,它可以对浮点行为进行一些检查。这是基于威廉·卡汉最初的偏执狂程序发现了臭名昭著的奔腾除法错误。
虽然它没有检测到我的测试系统的任何问题(因此不足以回答这个问题),但其他人可能会感兴趣。
- 使用CMake检测支持的C++标准
- 当套接字连接断开时检测C/C++Unix
- 函数何时会在c++中包含stack_Unwind_Resume调用
- C/C++预处理器是否可以检测一些编译器选项
- WMI检测进程创建事件-c++
- 通过网络、跨平台传递std::变体是否安全
- 基于树莓pi的tensorflow lite量化ssd目标检测
- Python中的for循环与C++有何不同
- 下面是我为检测链接列表中的循环而制作的代码
- 落砂模拟碰撞检测C++和SFML
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 为什么C++编译器没有检测到正确声明的类?
- 检测win32服务创建和删除的最佳方法
- 正在LLVM中检测整数比较条件
- 如何跨平台将二进制资源构建到程序中?
- 如何在鼠标挂钩过程中检测拖动
- 位移操作和位掩码未检测到重复字符
- 检测 COFF 对象文件中C++内联符号
- 如何检测跨平台浮点行为的差异
- 跨平台浏览器检测