我有一个非常奇怪的错误,我花了几天时间试图弄清楚,所以现在我想看看是否有人有任何评论来帮助我理解发生了什么。
一些背景。我正在开发一个软件项目,该项目涉及使用 Boost 1.45 将 C++ 扩展添加到 Python 2.7.1,因此我的所有代码都通过 Python 解释器运行。最近,我对代码进行了更改,它破坏了我们的一个回归测试。这个回归测试可能对数值波动(例如不同的机器)过于敏感,所以我应该解决这个问题。然而,由于这个回归是在产生原始回归结果的同一台机器/编译器上中断的,我将结果的差异追溯到这个数字代码片段(可验证这与我更改的代码无关):
c[3] = 0.25 * (-3 * df[i-1] - 23 * df[i] - 13 * df[i+1] - df[i+2]
- 12 * f[i-1] - 12 * f[i] + 20 * f[i+1] + 4 * f[i+2]);
printf("%2li %23a : %23a %23a %23a %23a : %23a %23a %23a %23a\n",i,
c[3],
df[i-1],df[i],df[i+1],df[i+2],f[i-1],f[i],f[i+1],f[i+2]);
它构造了一些数值表。注意:
- %a prints 提供精确的 ascii 表示
- 左侧(lhs)是 c[3],rhs 是其他 8 个值。
- 下面的输出是 i 的值远离 f, df 的边界
- 该代码存在于 i 上的循环中,该循环本身嵌套了多个层(因此我无法提供一个孤立的案例来重现此代码)。
所以我克隆了我的源代码树,我编译的两个可执行文件之间的唯一区别是克隆包含一些额外的代码,这些代码甚至在这个测试中都没有执行。这让我怀疑它一定是内存问题,因为唯一的区别应该是代码在内存中的位置......无论如何,当我运行这两个可执行文件时,它们产生的差异如下:
diff new.out old.out
655,656c655,656
< 6 -0x1.7c2a5a75fc046p-10 : 0x0p+0 0x0p+0 0x0p+0 -0x1.75eee7aa9b8ddp-7 : 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.1eaea08b55205p-4
< 7 -0x1.a18f0b3a3eb8p-10 : 0x0p+0 0x0p+0 -0x1.75eee7aa9b8ddp-7 -0x1.a4acc49fef001p-6 : 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.1eaea08b55205p-4 0x1.9f6a9bc4559cdp-5
---
> 6 -0x1.7c2a5a75fc006p-10 : 0x0p+0 0x0p+0 0x0p+0 -0x1.75eee7aa9b8ddp-7 : 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.1eaea08b55205p-4
> 7 -0x1.a18f0b3a3ec5cp-10 : 0x0p+0 0x0p+0 -0x1.75eee7aa9b8ddp-7 -0x1.a4acc49fef001p-6 : 0x1.304ec13281eccp-4 0x1.304ec13281eccp-4 0x1.1eaea08b55205p-4 0x1.9f6a9bc4559cdp-5
<more output truncated>
您可以看到 c[3] 中的值略有不同,而 rhs 值没有任何不同。因此,一些相同的输入会导致不同的输出。我尝试简化 rhs 表达式,但我所做的任何更改都会消除差异。如果我打印 &c[3],那么差异就会消失。如果我在我可以访问的两台不同的机器(linux、osx)上运行,则没有区别。这是我已经尝试过的:
- valgrind(在 python 中报告了许多问题,但在我的代码中没有任何问题,也没有任何看起来严重的问题)
- -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_ASSERT -D_GLIBCXX_DEBUG_PEDASSERT -D_GLIBCXX_DEBUG_VERIFY(但没有断言)
- -fno-strict-aliasing (但我确实从 boost 代码中得到了别名编译警告)
我尝试在有问题的机器上从 gcc 4.1.2 切换到 gcc 4.5.2,这种特定的、孤立的差异消失了(但回归仍然失败,所以让我们假设这是一个不同的问题)。
我能做些什么来进一步隔离问题吗?以供日后参考,有没有什么方法可以更快的分析或理解这类问题?例如,鉴于我对 lhs 变化的描述,即使 rhs 没有变化,你会得出什么结论?
编辑:问题完全是由于-ffast-math
.