CALL STORE(); widening; perfect conversions

Tim Peters uunet!ksr!tim
Tue Jun 12 21:44:15 PDT 1990


>  [nelson h. f. beebe]
>  ...
>  The workaround for systems that compute intermediate
>  expressions in higher precision (which is almost always a
>  good thing anyway) is to write
>
>       TEST1 = something not small
>       TEST2 = TEST1 + something possibly small
>       CALL STORE (TEST1)
>       CALL STORE (TEST2)
>       IF (TEST1 .NE. TEST2) ...
>
>  where STORE is a SEPARATELY-COMPILED routine that can in
>  fact do nothing to its argument; the compiler is forced to
>  assume that TEST1 and TEST2 may have been changed by the
>  calls, and therefore, to have stored them in memory, instead
>  of preserving them in longer registers.
>  ...

I'd like to second-- and maybe strengthen --David Hough's prescient
warning about the likelihood of this technique working in the future.
If you're letting your vendors (or asking your vendors to <grin>)
stick you with deficient compilers that ignore the std's guarantees
about the integrity of parentheses and statements, you've in fact
given up *every* defense the std guarantees, hence are left with
nothing that's guaranteed to work.  There's nothing that requires a
compiler to actually call an external routine, or flush COMMON blocks
to memory around calls, or store actual arguments to memory, or any of
the other things of this ilk we've come to expect from (most)
implementations.  Untold millions of dollars are being spent even as I
type finding ways to break the method above <grin -- could probably
say that less leadingly, eh?>.

David H correctly pointed out the dangers of optimizing linkers, and
those *are* on the way.  You can get burned at compile-time, too:  for
example, if you're building your executable from a UNIX(tm) makefile,
there's nothing to prevent a compiler from examining the rules,
determining how and where you build "STORE", and sucking STORE inline at
the source level.  People are looking at stuff like that too; the only
reason you've been "safe" so far is that people used to be sensible
enough not to carry everything in sight to extremes <grin>.

Seriously, if it ain't in the std and you rely on it, you better carry
a *lot* of clout with your vendors.


A bit more on widening computations:  I got a call last night from a
compiler developer who took me to task for claiming that in

      Z = X + Y + Z

(something like that) a conforming Fortran compiler could evaluate the
whole RHS in an extended precision before cutting it back to REAL.
And I think they were right -- I was wrong, too lenient.  The std
clearly defines the type of every subexpression in the evaluation to
be REAL, and the "mathematically equivalent" clause can no more allow
a processor to carry "extra bits" out of these REAL temps than it can
allow "extra bits" to be carried out of parentheses.  I'm not claiming
that these are ideal evaluation rules, but I do agree they are
Fortran's rules as the std is written today.  FYI, my caller said that
Kahan agreed (apparently reluctantly) to this interpretation of the
std in a private conversation last year (someone who knows him might
want to confirm or deny it?).

>  >[tgp extolling the virtues of perfect conversions & challenging
>  > david k to trade in his bearskin for a suit] 
>  [david keaton]
>       I don't dispute that these problems exist.  In fact, I would
>  prefer perfect conversions personally.  But none of the problems we
>  have discussed outweigh performance until most Cray-class customers
>  tell me they do.  The marketplace is simply telling me "Don't fix this
>  unless you can do it without hurting performance."
>
>       Now, it is possible that an implementation will be found that
>  does not affect performance.  In that case, all my objections vanish.

I can't (OK, won't <grin>) argue with that.  Thanks for clearing it
up.  I finally got an hour to study the "perfect conversion" papers
recently mentioned here, and highly recommend them to everyone.  Alas,
they're *real* promising in the "typical cases", but it leads to a
"...  and then a truck came along & ran everyone over & they all died"
kind of ending.  I.e., the worst-case performance is almost
unthinkably bad if adapted for a Cray.  Unsurprisingly, the *real*
headaches are caused by large-magnitude exponents, and because Cray's
64-bit format has about eight times the dynamic range of 754's 64-bit
format, the worst cases would oblige you to fake exact integer
arithmetic on operands exceeding 8,000 bits (if my back-of-
the-envelope calculations are correct -- pretty sure they are).  Still
worth looking at, though; depends on just how rare the terrible cases
are in practice (although the typical cases are likely 2+ X as slow
as the NICV/NOCV I last saw too).  Guess I didn't really fire your
enthusiasm <grin>?

failing-to-convert-the-unconverted-to-perfect-conversion-ly y'rs  -
   tim

Tim Peters   Kendall Square Research Corp
timaksr.com,  ksr!timaharvard.harvard.edu



More information about the Numeric-interest mailing list