Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Sep 2012 14:01:39 -0500
From:      Stephen Montgomery-Smith <stephen@missouri.edu>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        freebsd-numerics@FreeBSD.org
Subject:   Re: Complex arg-trig functions
Message-ID:  <50562213.9020400@missouri.edu>
In-Reply-To: <20120917022614.R2943@besplex.bde.org>
References:  <5017111E.6060003@missouri.edu> <50297E43.7090309@missouri.edu> <20120814201105.T934@besplex.bde.org> <502A780B.2010106@missouri.edu> <20120815223631.N1751@besplex.bde.org> <502C0CF8.8040003@missouri.edu> <20120906221028.O1542@besplex.bde.org> <5048D00B.8010401@missouri.edu> <504D3CCD.2050006@missouri.edu> <504FF726.9060001@missouri.edu> <20120912191556.F1078@besplex.bde.org> <20120912225847.J1771@besplex.bde.org> <50511B40.3070009@missouri.edu> <20120913204808.T1964@besplex.bde.org> <5051F59C.6000603@missouri.edu> <20120914014208.I2862@besplex.bde.org> <50526050.2070303@missouri.edu> <20120914212403.H1983@besplex.bde.org> <50538E28.6050400@missouri.edu> <20120915231032.C2669@besplex.bde.org> <50548E15.3010405@missouri.edu> <5054C027.2040008@missouri.edu> <5054C200.7090307@missouri.edu> <20120916041132.D6344@besplex.bde.org> <50553424.2080902@missouri.edu> <20120916134730.Y957@besplex.bde.org> <5055ECA8.2080008@missouri.edu> <20120917022614.R2943@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 09/16/2012 11:51 AM, Bruce Evans wrote:

>
> I don't like that.  It will be much slower on almost 1/4 of arg space.
> The only reason to consider not doing it is that the args that it
> applies to are not very likely, and optimizing for them may pessimize
> the usual case.

The pessimization when |z| is not small is tiny.  It takes no time at 
all to check that |z| is small.

On the other hand let me go through the code and see what happens when 
|x| is small or |y| is small.  There are actually specific formulas that 
work well in these two cases, and they are probably not that much slower 
than the formulas I decided to remove.  And when you chase through all 
the logic and "if" statements, you may find that you didn't use up a 
whole bunch of time for these very special cases of |z| small - most of 
the extra time merely being the decisions invoked by the "if" statements.

> I just found a related optimization for atan2().  For x > 0 and
> |y|/x < 2**-(MANT_DIG+afew), atan2(y, x) is evaluated as essentially
> sign(y) * atan(|y|/x).  But in this case, its value is simply y/x
> with inexact.  Again the optimization applies to almost 1/4 of arg
> space.  It gains more than the normal overhead of an atan() call by
> avoiding secondary underflows when y/x underflows.

You see, that is exactly where I don't want to do special optimization 
in my code.  In my opinion, it is the tan function itself that should 
realize that |y|/x is small, and hence it is that function that simply 
return |y|/x.  Or if you want to implement it at a higher level, atan2 
should make this realization, and simply return y/x.

Similarly, I would expect log1p(x) to simply return x (inexactly) for x 
small.  And if the compiler is really good, I would hope that the two codes:
log1p(x);
(fabs(x) < DBL_EPSILON) ? x + set_tiny() : log1p(x);
would be equivalent.  (But I am rather sure that gcc isn't that good.)

Furthermore, casinh etc are not commonly used functions.  Putting huge 
amounts of effort looking at special cases to speed it up a little 
somehow feels wrong to me.  In fact, if the programmer knows that he 
will be wanting casinh, and evaluated very fast, then he should be 
motivated enough to try out using z in the case when |z| is small, and 
see if that really speeds things up.

Stephen




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?50562213.9020400>