visual c++中,没有编译器优化的数字代码会给出错误的结果

visual c++, numerics code without compiler optimization gives wrong results

本文关键字:代码 数字 出错 结果 错误 优化 c++ 编译器 visual      更新时间:2023-10-16

我在Visual C++编译器优化方面遇到了一个奇怪的情况。

在一个相当中等大小的c++代码中,有10个静态库,如果在优化为On(/O1、/O2或/Ox)的情况下编译代码,则程序的运行会产生正确的输出。

不过,使用/Od时,程序会产生错误的输出。

我知道这个问题很普遍,但我很感激任何关于原因的线索,或者它与什么有关的线索。

p.s.代码是在做FEM数字运算,所以很多是浮点运算。p.s.代码在Visual Studio 2010中。

编辑:代码的示例输出:

r(残差)的差异是相当大的

I没有优化:

Solver. time: 0.12, iteration: 1
Solver.
------------------------------------
determining values:
dg.            0
limit of dg.   0.897278
dr.            7675.3
limit of dr.   45.3704
r.             7675.3
limit of r.    453.704
dx.            0.122164
limit of dx.   8.97278e-005
------------------------------------

II带有优化:

Solver. time: 0.12, iteration: 1
Solver.
------------------------------------
determining values:
dg.            0
limit of dg.   0.897278
dr.            5894.53
limit of dr.   45.3704
r.             5894.53
limit of r.    453.704
dx.            0.122164
limit of dx.   8.97278e-005
------------------------------------

p.s.我不能提供代码本身的示例,因为我真的不知道问题是从代码中的哪里产生的。

错误被发现,它是未初始化的变量,看起来像是初始化的!我在numerics库中定义了一个(双)常数kInfinity值。其他库(fem,它们在很大程度上依赖数字库)在程序开始时从数值程序库获取此值,以便在稍后的程序运行中使用此值。问题是,他们在之前就取了这个值,它首先在数字库中初始化(这就像一场比赛。)

现在是有趣的部分:

  • 在没有优化的情况下,编译器将未初始化的变量设置为"零"(非常著名的行为)。如果在"线性弹性材料模型"中使用这样的值作为"屈服应力",则意味着非物理材料,这意味着代码无法产生有趣的输出。

  • 通过优化,编译器将未初始化的变量设置为"随机"(在我的情况下是非常大的)数字。如果在"线性弹性材料模型"中使用这样的值作为"屈服应力",那么这完全意味着线性弹性材料(相当物理)

这解释了为什么通过优化我的代码可以工作,但并非没有。

感谢所有的回复和分享想法。

这很难说,但优化可以删除一些算术表达式,并放入"优化"的表达式。通过修改包含加法、乘法等运算的算术表达式,结果会受到影响。你可能会有溢出,精度损失。。。

相关文章: