Float values ​​behave differently in release and debug builds

My application generates different floating point values ​​when I compile it in release mode and debug mode. The only reason I found out is to keep the binary trace log, and the one that is so little detuned from the release build from the debug build, it seems that the bottom two bits of the 32-bit float values ​​are different from 1/2 of the case.

Would you consider this “difference” a mistake or expect such a difference. This will be a compiler error or an internal library error.

For example:

LEFTPOS and SPACING are defined floating point values. float def_x; int xpos; def_x = LEFTPOS + (xpos * (SPACING / 2)); 

The problem is with the X360 compiler.

+6
c ++ c compiler-construction floating-point debugging
source share
9 answers

Release mode may have a different FP strategy. There are various floating point arithmetic modes depending on the level of optimization you want. For example, MSVC has strict, fast and accurate modes.

+11
source share

I know that on a PC, floating point registers are 80 bits wide. Therefore, if the calculation is performed completely inside the FPU, you get an advantage of 80 bits of accuracy. On the other hand, if the intermediate result is moved to the regular register and vice versa, it is truncated to 32 bits, which gives different results.

Now consider that a release build will have an optimization that stores intermediate results in the FPU register, while a debug assembly will probably naively copy intermediate results back and forth between memory and registers - and there you have a difference in behavior.

I do not know if this is the case on the X360 or not.

+4
source share

I helped an employee find a compiler that was different in the release and debug versions that caused its differences.

Take a look at / fp (specify floating point behavior) .

+3
source share

It's not a mistake. Any floating point deviation has a certain inaccuracy. In Release mode, optimization will change the order of operations, and you will get a slightly different result. However, the difference should be small. If it is large, you may have other problems.

+2
source share

In addition to the various floating point modes that others have indicated, SSE or similar vector optimizations may be included for release. Converting floating point arithmetic from standard registers to vector registers can affect the lower bits of your results, since vector registers will usually be narrower (fewer bits) than standard floating point registers.

+2
source share

Not a mistake. This type of difference can be expected.

For example, on some platforms there are floating point registers that use more bits than are stored in memory, so storing a value in a register can give a slightly different result compared to storing in memory and reloading from memory.

+1
source share

This mismatch may be caused by compiler optimizations, which typically occur in release mode, but not in debug mode. For example, the compiler may reorder some of the operations to speed up execution, which seems to cause a slight difference in the floating point results.

So, I would say, most likely, this is not a mistake. If you are really worried about this, try turning on Debug Optimization.

0
source share

Like many others, floating point registers have higher accuracy than floating point registers, so the accuracy of the final result depends on the distribution of the registers.

If you need consistent results, you can make volatile variables, which will lead to slower, less accurate, but consistent results.

0
source share

If you set the compiler switch that allowed the compiler to reorder floating-point operations — for example, / fp: fast — then obviously this is not an error.

If you did not install any such switch, then this is a mistake - the C and C ++ standards do not allow compilers to reorder operations without your permission.

0
source share

All Articles