Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: [OT] Re: Java oddity

Author: Robert Hyatt

Date: 08:50:38 09/11/02

Go up one level in this thread


On September 10, 2002 at 21:18:45, Eugene Nalimov wrote:

>Lot of compilers, including Visual C, can produce either fast but
>non-IEEE-compliant, or relatively slow, but consistent code. It happens that lot
>of people are ready to lost some FP accuracy but gain some speed in return.

These are all pretty well-known.

But I was talking specifically about the idea of replacing a division with
a constant with a multiply by a less-accurate constant...  I haven't seen
that done.  I've seen the divides moved out of a loop many times.  On the
cray, computing 1/x and multiplying is the _only_ way to divide..  and there
you end up with the same problem,  but dividing by 1000 produces an 80 bit
result, with the most significant errors in the low-order end, outside the 64
bit part.  multiplying by .001 introduces the most significant part of the
error into the 64 bit (assuming IEEE 64 bit here) part, rather than farther out
in the guard digits.



>
>Several trivial examples of the numerically unsafe but common optimizations:
>
>Replacing division by loop-invariant value by multiplication, i.e.
>    for (i=0; i<100; i++)
>        a[i] = b[i]/x;
>would be replaced by
>    y = 1./x;
>    for (i=0; i<100; i++)
>        a[i] = b[i]*x;
>
>Expression reordering:
>    x = a+b+c+d;
>would be replaced by
>    x = (a+b)+(c+d);
>
>Reductions:
>    for (i=0; i<100; i++)
>        s += a[i]*b[i];
>would be replaced by
>    s1 = 0.0;
>    for (i=0; i<100; i+=2) {
>        s += a[i]*b[i];
>        s1 += a[i+1]*b[i+1];
>    }
>    s += s1;
>
>Removing multiplications by zero, additions with zero, etc. Surprisingly, those
>optimizations should not be done by the IEEE-compliant compiler!
>
>And of course there are "real" optimizations done by "real" heavy-FP-optimizing
>compilers -- blocking, peeling, etc.
>
>Thanks,
>Eugene
>
>On September 10, 2002 at 20:04:16, Robert Hyatt wrote:
>
>>On September 10, 2002 at 19:41:53, Dieter Buerssner wrote:
>>
>>>On September 09, 2002 at 23:10:20, Robert Hyatt wrote:
>>>
>>>>I can't believe _any_ compiler would use .001 since it can't be converted
>>>>to IEEE FP exactly.  Dividing by 1000 is far more preferable as 1000 _can_
>>>>be converted exactly.
>>>
>>>gcc -ffast-math
>>>
>>>Often (mostly?) this is nice. For example
>>>
>>>  double a, b, c, d;
>>>
>>>  /* I don't care about the last bit (only this can be different), but about
>>>     speed */
>>>  a /= d;
>>>  b /= d;
>>>  /* Or should I write:
>>>  c = 1.0/d;
>>>  a *= c;
>>>  b *= c;
>>>  A clever compiler may know, which is faster for this specific architecture.
>>>  Many algorithms will work well either way, so one prefers the fastest method.
>>>  A strict IEEE-conforming floating point environment, of course must not
>>>  rearrange such expressions.
>>> */
>>>
>>>Regards,
>>>Dieter
>>
>>That is a different issue IMHO.  IE certainly you want to avoid divisions on
>>the Cray since it could not divide.  In fact, it had a "reciprocal
>>approximation" instruction that computed 1/x to whatever accuracy you wanted.
>>
>>But if I give a compiler the /10 type operation, it should prefer that to
>>*.1, because the /10 has enough error in it, the *.1 adds move because it
>>is non-representable in a perfect conversion.
>>
>>I was commenting about the compiler arbitrarily replacing /1000.0 with
>>*.001, which would seem to be bad math...



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.