be careful about optimizing a+b-a-b !

Thomas M. Breuel uunet!idiap.ch!tmb
Sat May 9 00:54:01 PDT 1992


|Compiler writers would do us a favor by NOT doing us a favor by optimizing
|away a+1-a-1 in the foregoing to zero.  The whole point of the computation
|is to detect the roundoff error.   Unfortunately in the rush to better
|SPECmarks, some people may succumb to temptation.

I have little sympathy for this argument. Detecting roundoff error in
the way you describe is non-portable in C; hence, you need to do some
work when you move it to a different machine.  You can easily make the
code "more portable" by inserting "volatile" or other kinds of code
(but in many cases, a compiler could still legally ignore all your
efforts and optimize the expression anyway).

To me, the right semantics for optimizing numerical computations are
pretty clear:

 * the optimization is legal iff it always results in a value
   that is closer to the mathematical result than the
   unoptimized version ("unoptimized version" is defined by
   whatever formal way you like to use to specify what your
   programming language does).

 * optimizations may be performed even if they eliminate
   potential overflows or underflows (but the optimization may not 
   extend the mathematical domain of a function; hence, "f(x) = x/x"
   may not simply be optimized to "f(x) = 1", but can be optimized to 
   "f(x) = if x=0 then raise Division else 1".

One choice that you have is to provide both styles of optimization
via a pragma: (1) guaranteed bitwise equality, and (2) optimized
results that are no less accurate than unoptimized results. I suspect
that most people prefer (2) for day-to-day work (and that's what I
described above).

I think, ultimately, these issues should be resolved by formal
specifications of floating point computation and floating point
optimizations (don't leave it up to the compiler writers!), but
that's probably not practical right now.

				Thomas.



More information about the Numeric-interest mailing list