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

时间:2013-08-24 11:06:50

标签: c# debugging visual-studio-2012 floating-point testdriven.net

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

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

代码是

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

我没有追溯到第一个区别(没有调试器就很棘手!)但考虑到代码是如何迭代的,它的输入敏感度和最微小的差异会在给定足够时间的情况下显着增加。

我知道编译器,平台和架构之间的fp重现性是多么脆弱,但却发现调试器是解决这个问题的因素之一。

我是否必须接受这一事实,或者您可以提供任何建议吗?

1 个答案:

答案 0 :(得分:9)

  

我是否必须接受这一事实,或者您可以提供任何建议吗?

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

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