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>