浮点差异取决于调试构建的运行方式

我正在使用调试版本并在同一台机器上获得不同的结果,无论我是否在调试器下运行。 我使用优秀的TestDriven.Net来运行unit testing。

  • 使用TestDriven.Net或外部NUnit运行程序“运行”会产生相同的结果
  • 使用TestDriven.Net“使用调试器运行”会产生不同的结果

代码是

  • 一种复杂的迭代网格变形程序,涉及浮点精度极限的重要计算
  • C#,VS2012瞄准.Net 3.5。
  • 单线程
  • 只有调试版本,没有构建版本
  • 同一台机器,没有省电\ speedstep或我所知道的其他function
  • Vanilla C# – 没有不安全的代码,非托管库,平台调用等。
  • 没有调试器检查代码或奇怪的第三方库

我没有追溯到第一个区别(没有调试器就很棘手!)但考虑到代码是如何迭代的,它的输入敏感性和最小的差异将在给定足够时间的情况下增长到相当大的比例。

我知道编译器,平台和架构之间的fp重现性是多么脆弱,但是发现调试器是导致这种情况失败的因素之一令人失望。

我是否必须接受这个作为生活中的事实,或者您可以提供任何建议吗?

我是否必须接受这个作为生活中的事实,或者您可以提供任何建议吗?

你必须接受它作为生活中的事实。 浮点代码可以在不同情况下进行不同的优化。 特别是,在某些情况下,JIT编译器可以使用具有更高精度/准确度 (例如,80位浮点)的表示来进行操作。 JIT编译器执行此操作的情况将取决于体系结构,优化设置等。对于您对变量执行的操作(以及是否为局部变量)可能存在任何可能影响此变量的细微之处。 在调试器下运行通常会非常显着地影响JIT优化设置 – 不仅仅是浮点数 – 所以我对此并不感到惊讶。

如果你执行具有一定容差的浮点比较,它应该没问题 – 无论如何,对浮点类型进行精确的相等比较是一个很好的主意。 当然,你可能实际上在差异变得显着的情况下进行非平等比较,但我很少将其视为一个问题。