Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Sep 2012 15:53:43 -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:  <50563C57.60806@missouri.edu>
In-Reply-To: <20120917060116.G3825@besplex.bde.org>
References:  <5017111E.6060003@missouri.edu> <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> <50562213.9020400@missouri.edu> <20120917060116.G3825@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 09/16/2012 03:29 PM, Bruce Evans wrote:
> On Sun, 16 Sep 2012, Stephen Montgomery-Smith wrote:
>
>> 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.
>
> Not necessarily on out-of-order machines (most x86).  The CPU executes
> multiple paths speculatively and concurrently.  If it does more on an
> unused path, then it might do less on the used path.  It may mispredict
> the branch on the size of |z| and thus misguess which path to do more
> on.  (I don't know many details of this.  For example, does it do
> anything at all on paths predicted to be not taken?)  Losses from this
> are usually described as branch mispredictions.  They might cost 20
> (50? 100?) cycles after taking 2 about cycles to actually check |z|
> (2 cycles pipelined but more like <length of pipe> + 8 in real time,
> and it is the latter time that you lose by backing out).
>
> The only sure way to avoid branch mispredictions is to not have any,
> and catrig is too complicated for that.

Yes, but I did a time test.  And in my case the test was almost always 
failing.

>
>> 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.
>
> But all general cases end up going through an extern function like
> acos() or atan2(), and just calling another function is a significant
> overhead.  When |z| is small, the arg(s) to the other function will
> probably be an special case for it (e.g., acos(small)).  The other
> function should optimize this and not take as long as an average call.
> However, since it is special, it may cause branch mispredictions for
> other uses of the function.

I understand what you are saying.  I guess it just seems to me that the 
"proper" way to do it is to make the C compiler really awesome and do 
this for you.  (Doesn't the Intel compiler try to embed functions inline 
if it knows it will speed things up)?

>> 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.

Well, if casinh goes 20% slower, your not going to be testing too many 
fewer cases.

> True.  Now I mainly want it to be fast so that I can test more cases.

I understand.  But putting those special cases into casinh offends my 
sense of taste.




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