Date: Sun, 10 May 2015 11:59:55 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Steve Kargl <sgk@troutmask.apl.washington.edu> Cc: freebsd-numerics@freebsd.org Subject: Re: small cleanup patch for e_pow.c Message-ID: <20150510113454.O841@besplex.bde.org> In-Reply-To: <20150510002910.GA82261@troutmask.apl.washington.edu> References: <20150510002910.GA82261@troutmask.apl.washington.edu>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 9 May 2015, Steve Kargl wrote: > In reading, e_pow.c I found a small piece of code that > can be remove. Anyone object? > > Index: src/e_pow.c > =================================================================== > --- src/e_pow.c (revision 1603) > +++ src/e_pow.c (working copy) > @@ -187,10 +187,6 @@ __ieee754_pow(double x, double y) > > /* |y| is huge */ > if(iy>0x41e00000) { /* if |y| > 2**31 */ > - if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */ > - if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny; > - if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny; > - } > /* over/underflow if x is not close to one */ > if(ix<0x3fefffff) return (hy<0)? s*huge*huge:s*tiny*tiny; > if(ix>0x3ff00000) return (hy>0)? s*huge*huge:s*tiny*tiny; It seems to be just an optimization. It is a large optimization for the huge args, but those are not common, and is at most a tiny pessimization for non-huge args (just an extra branch which can be predicted perfectly if non-huge args are never used). My tests cover huge args uniformly in float space, so they benefit from optimizations like this more than normal programs. However, on some CPUs the exceptions for calculating huge*huge and tiny*tiny when they overflow/underflow are the main source of slowness, so it doesn't help much to avoid large code that has to be executed for normal args, unless the latter would generate multiple exceptions. Here if you are correct that the above code can be removed, then the exceptions generated by the main path can't be too complicated or it would be hard to see that there are no spurious ones. We can see this easily for functions like exp(), and pow() is not very different, because the algorithm is basically to calculate a small result and then multiply it by 2**k. The overflows and underflows only occur in the scaling step. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150510113454.O841>