可能的编译器错误:在两台机器之间使用带有英特尔编译器的 boost bessel 函数的奇怪结果?
Posted
技术标签:
【中文标题】可能的编译器错误:在两台机器之间使用带有英特尔编译器的 boost bessel 函数的奇怪结果?【英文标题】:Possible compiler bug: Weird results using boost bessel functions with Intel compiler between two machines? 【发布时间】:2014-03-04 17:06:08 【问题描述】:我正在尝试在项目中使用 boost 的贝塞尔函数 (cyl_bessel_j)。但是,我发现该函数在大约 2000 次调用后返回带有错误符号的结果。
我已经在两台机器之间进行了测试,一台是 CentOS 5.8(Final)机器,它在其中运行得非常奇怪,另一台是 RHEL 6.3(圣地亚哥)机器,它失败了。
两台机器都使用 Boost 1.50.0 和 13.1.3 20130607 Intel 编译器。 CentOS机器使用gcc 4.1.2 20080704,RHEL机器使用gcc 4.4.6 20120305。
这是我的代码:
template<typename FloatType> FloatType funcT(FloatType z, FloatType phi,
int n, int m, int p)
using namespace boost::math;
FloatType sqrt2PiZ = sqrt((2 * M_PI)/z);
FloatType nrmLeg = normalizedLegendre(n,m,-sin(phi));
FloatType besselJ = cyl_bessel_j(p + 0.5, z);
std::cout << " " << p << "," << z << " besselJ: " << besselJ << std::endl;
return sqrt2PiZ * nrmLeg * besselJ;
在两台机器上运行时,我发现两者之间唯一不同的术语是 besselJ 术语。对于 1980 年对该函数的第一次调用,它们返回相同的结果,但是,在第 1981 次调用中,RHEL 机器突然切换其结果的符号。前几个失败的术语打印如下(RHEL SIDE):
...
1,7.90559 besselJ: -0.0504874
2,7.90559 besselJ: 0.264237
3,7.90559 besselJ: 0.217608
...
在 MATLAB 中使用 besselJ 函数运行参考测试,我发现对于这些输入,符号应该是相反的,而且 CentOS 机器确实与 MATLAB 一致。
我决定用 besselJ 函数编写一个简单的 hello-world 样式示例来尝试确定失败的原因:
#include <boost/math/special_functions/bessel.hpp>
#include <iostream>
int main(int argc, char** argv)
double besselTerm = boost::math::cyl_bessel_j(1.5, 7.90559);
std::cout << besselTerm << std::endl;
此测试在 BOTH 机器上返回预期值 0.0504874。
此时,我正在努力确定问题的原因。这似乎是一些奇怪的编译器错误或堆栈损坏。但是,堆栈损坏如何给出除了一个位之外的确切正确答案?
有没有人在使用 boost 或 Intel 编译器时遇到过类似的问题?
其他信息: 已经发现,带有 --fast-math 标志的 GCC 4.4.6 上的最小案例测试会中断。通过使用 -std=c++11 标志(这是较大的项目使用的),我还能够使英特尔编译器失败的最小测试用例。
【问题讨论】:
boost::math::cyl_bessel_j
的输入真的一样吗?还是它们与 LSB 不同,而那些数字只是没有被打印出来。
它们是一样的。如果不是,则两台机器的 sqrt2PiZ 术语将不同,我已经验证该术语是相同的。
看起来它们甚至在打印输出 1,7.90559 besselJ: -0.0504874
和最小示例 cyl_bessel_j(1.5, 7.90559)
之间也有所不同。
现在这很奇怪。你是如何进行测试的?我的最小示例在两台机器上都给出了积极的信号。
有趣。根据--fast-math
的存在/不存在,我得到不同的结果(仅在符号上有所不同)。 4.8.1-10ubuntu9
。也许这是一个错误。我的猜测是,对于错误报告来说,这可能还不够小。看看你是否能分辨出 cyl_bessel_j
内部哪里出了问题。
【参考方案1】:
一个错误已提交到 boost 库 trac 系统。
然而,发现问题出在 std c++ 库中,表明 GCC 4.4.7 中存在问题。
Boost 开发人员创建了解决此问题的解决方法补丁: https://github.com/boostorg/math/commit/9f8ffee4b7a3f82b1c582735d43522d7d0cde746
【讨论】:
以上是关于可能的编译器错误:在两台机器之间使用带有英特尔编译器的 boost bessel 函数的奇怪结果?的主要内容,如果未能解决你的问题,请参考以下文章
同一个C语言程序,若在两台不同指令系统的机器上运行,编译后的程序是不是一样?能否用同一个编译器编译?