Different results that shouldn't differ

Different results that shouldn't differ

I am trying to track down differences between two versions of a code that should produce identical results. I have tracked down the first difference to the following line of code:

X(I) = RHO(KT,I)*G*COSA(JB)*DLT*DLT*(BHRHO(I)*0.5/DLXR(I)+BHRHO(I-1)*0.5/DLXR(I-1))+DLX(I)*B(KTI(I),I)

the results in hexadecimal for the old and new versions are

41E9DEF00422F1C3 - old
41E9DEF00422F1C4 - new

When I split the right hand side into the following expressions

RHO(KT,I)*G*COSA(JB)*DLT*DLT

(BHRHO(I)*0.5/DLXR(I)+BHRHO(I-1)*0.5/DLXR(I-1))+DLX(I)*B(KTI(I),I)

and view in the debugger I get the following results

423D98D5E5D8E880 - old
413304E33A30B89B - old

and

423D98D5E5D8E880 - new
413304E33A30B89B - new

How can the intermediate results be the same between the old and the new code, but, when I multiply the two expressions, end up with a different result?

6 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

To tell for sure, you'd have to look at the object
code from each version, and the values in all of the
floating point registers,plus all of the variables. Take a simple example:

x = a + b + c

The compiler might do this as (a + b) + c or
a + (b + c) or (a + c) + b, any of which is allowed
since the order was not explicitly set using parentheses
and any of which could give a slightly different
result depending on the values of a, b, and c.
Other differences can crop up depending on whether
an intermediate result gets to stay in a floating point
register (which has more precision than a real*8)
or if it gets stuffed into a temporary variable.

Jim, thanks, but explain how the statement

x=a+b+c

can yield different results using the exact same expression. From what you are telling me, in one code the compiler is computing it as (a+b)+c and in what is almost the identical code it is computing it as a+(b+c). How is that possible for the compiler to arbitrarily group the order of calculations? This would imply that the ordering of expression evaluation using the same operator is random. As a workaround, I'm going back to single precision arithmetic to wipe out the differences, but they shouldn't be different.

Actually the CVF documentation says that it
would do the A+B+C example in left-to-right order.
I think, in general, reordering is permitted but
CVF apparently doesn't do it. Gotta track down
that thread in comp.lang.fortran

OK, found the thread. Check the google archive
in comp.lang.fortran for the thread

What algorithm for SUM intrinsic?

which talks about being able to reorder computation
in a mathematically equivalent way.

Actually, after reading this thread I'm not quite
sure whether CVF might reorder the A+B+C example after
all. That left-to-right business might be talking
about how to treat something like A/B/C.

How is X(I) declared? Do all variables have the same type? I mean, such things happen when you mix Real and Real*8 in the same equation. Besides, you should have 0.5D0 instead of 0.5 in the calculation, if you have declared your variables as double precision.

Sabalan.

Login to leave a comment.