Archived

This topic is now archived and is closed to further replies.

iwaskia

which is faster? a*a or sqrt(a)

Recommended Posts

Guest Anonymous Poster
quote:
Even if the sqrt function didn''t do anything the multiply would be faster.


not quite. if you had sqrt mapped to do nothing (NOOP, 0, NULL,etc.. ). nothing would be done. nothing is faster than a multiply.

alienid..there is no guessing in the sqrt function. if your doing something that needs absolute precision, you wouldnt be using sqrt anyways.

Share this post


Link to post
Share on other sites
AP, even if sqrt() did nothing at all except return a constant float (since at the very least it MUST do this in order to be valid in this context), at best you can get similar speeds. at worst, its much slower (ie the compiler does not inline the function). no inline means at minium you will have at least a CALL, NOP, RET, which under the hood will push the current address onto the stack and pop the address for the return jmp when done. also you will have to push the arg, and pop the result. much more then just doing a multiplications, i would say. if you dont believe me, code a simple test app that uses QueryPerformenceCounter(). just make sure you are fair and have both methods start at 0.0 and increment a.

AP, the problem is you dont understand function calls, nor how cpus work. i highly suggest learning ask and about compilers before spewing false information.

A*A is faster then sqrt().

Share this post


Link to post
Share on other sites
I''m not going to go into detail here...but the basic algorithim for finding square roots is like a more complex version of long division.

However, you could implement a approximation using ''cut and try''
IE, take a number, multiply it by itself, see if its near the number you need, if its not, find another number, if it is, jump , if that is further away, jump in the other direction.

If you are do a num*num, that is at most 3 lines of asm, I think.
Its a simple mul instruction, and a assignment.

So it obvoius that the sqr is faster.
Prsonally, I have a #define sqr directive- I`ve had to use num*num so much,
It goes like so....

#define sqr(num) num*num

:D

How to make a fast sqrt, I dont know. Sorry !

Bugle4d

Share this post


Link to post
Share on other sites
Finding the square root is very slow but there is a x87 math assembly instruction, fsqrt, to do it, which is at least faster than any software implementations. But it's still slow.

A mere square, on the other hand, is just a multiplication and is much faster.

~CGameProgrammer( );

EDIT: The sqrt() function almost definitely calls the assembly command.

[edited by - CGameProgrammer on April 30, 2002 1:48:00 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
[quote]Even if the sqrt function didn''t do anything the multiply would be faster.


not quite. if you had sqrt mapped to do nothing (NOOP, 0, NULL,etc.. ). nothing would be done. nothing is faster than a multiply.

alienid..there is no guessing in the sqrt function. if your doing something that needs absolute precision, you wouldnt be using sqrt anyways.



Why would you do that.
Heas asking if, ie, 3*3 and sqrt(4), not nothing*nothing and sqrt(nothing)

[ my engine ][ my game ][ my email ]
SPAM

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster

Even if the sqrt function didn''t do anything the multiply would be faster.


not quite. if you had sqrt mapped to do nothing (NOOP, 0, NULL,etc.. ). nothing would be done. nothing is faster than a multiply.


A function call is slow, even if the function doesnt do anything. If the function was precompiled into a library, it couldnt be inlined. Even if it was inlined, the stack manipulations (pushes and pops) are numerous and aren''t likely to be optimized away.



"I believe; therefore, it is." -True Perception
"The Requested Information Is Unknown Or Classified" -Anonymous

Share this post


Link to post
Share on other sites
if a is a non-variable constant it is done at compile time. In that case speed is not an issue. If a is a viariable a*a would always be faster than any function call (especially if teh function takes variables)

Reality Makes Me XiC
I don''t do talk, I code: passion is my feul. Use my programs, experience beauty.
http://www.x-i-c.com/

Share this post


Link to post
Share on other sites
quote:

#define sqr(num) num*num




    
#include <iostream>


// #define sqr(num) num*num


#define sqr(num) ((num)*(num))


int main()
{
cout << sqr(1+3) << endl;
// one way you get 1+3*1+3, 7, the other you get ((1+3)*(1+3)), 16.


return 0;
}


[edited by - smart_idiot on April 30, 2002 12:34:09 PM]

Share this post


Link to post
Share on other sites
and sqr(x++) will always result in a wrong value, cause it gets expanded to x++*x++ or (x++)*(x++), and, as you see, it gets incremented 2 times..

NEVER USE MAKROS.. bether use templates if you really need that..

template inline Type sqr(const Type& x) {
return x*x;
}

on every normal intelligent compiler this will be as fast as your macro, but this time no bugs in.. wow





oh, and sqrt does NOT use any ifs and elses in, cause math don''t like ifs and elses (or have you seen them yet in formulas in school?)

dunno how they implemented it, but well..

sqrt(x) = x^.5

as x is a float, its build by mantissa and exponent like this:

x = m*2^e where m is a mantissa from 0 to 1, and e is from -127 to 127 (uh no, thats for doubles i guess..)

so sqrt(x) = (m*2^e)^.5 wich results in m^.5 * 2^.5e

now .5e is fast calculated, and stored in the exponent back again (just shift the exponent to the left 1 bit)

now doing the stuff for the mantissa.. m^.5 is a value from 0 to 1.. there tailors always work wonders.. now (1+a)^.5 can be expanded with the binomial-series, and if you say a = m-1, (1+a)^.5 results in (1+m-1)^.5 = m^.5 = what we want.. a is between -1 and 0, wich is quite good for the tailors as well (as higher powers of a move more near to zero..)

now for an accurate sqrt, you shift the exponent by one, and use a very good serie of the binomials (wich result in some func like this: a*(1+b[0]*a*(1+b[1]*a*(1+b[2]*a*(....
wher the b[x] are the correct coeffizients for (1+a)^.5

as you see, for an accurate sqrt (means the error of the approximation is less that the float or double can store), you need quite a lot of multiplications..

a*a is ALWAYS faster..

"take a look around" - limp bizkit
www.google.com

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
ok, i wasnt clear...it was in response to siaspete''s even if the sqrt doesnt do anything comment..

i meant..

#define I_BE_NOT_NEEDING_NO_STINKING_SQRT 1

#if I_BE_NOT_NEEDING_NO_STINKING_SQRT
#define sqrt(x) 0
#else
#define sqrt(x) sqrt(x)
#endif

this is faster than a multiply.

a person..whats that? the compilier can put a 0 in the place of the function call..no way! ok, maybe for some compiliers youd need to call the define mysqrt() instead of sqrt()..but lets not get nitpicky shall we..

AP-1
a person-0

: )

Share this post


Link to post
Share on other sites
quote:
Original post by davepermen
NEVER USE MAKROS.. bether use templates if you really need that..


why would you say that? just because it is possible to introduce problems using macros doesn''t mean you shouldn''t use them! macros can be very useful. If you don''t want to use them that''s fine, but you shouldn''t discourage other people from learning how to use them (and correctly) just because you don''t like them. Obviously you know some of the problems that can arise from using them, but it is possible and, once you know how, easy to avoid these problems. macros were invented for a reason, after all.

ewen

Share this post


Link to post
Share on other sites
Anonymous Poster, you really dont understand what you are saying. doing absolutly nothing is not the same as calling a function which does nothing. we were discussing calling a function that does nothing vs a multiply. you are merely erasing the function call from existence, and the compiler never even sees the call. you are not being clever, but rather ignorent of things.

so i guess that makes it
#define AP 0
heh, could not resist.

btw, AP, that is a GREAT optimization technique. you should write an article to gamedev on it.

[edited by - a person on April 30, 2002 12:51:16 AM]

Share this post


Link to post
Share on other sites
Even if you called a function that does nothing (e.g. sqrt(x) as AP put it) you are still passing in a variable.

Memory on the stack must be reserved for the function. And the copy constructor for the variable passed into the function will be called, which entails memory being reserved on the stack for that variable and an assignment statement taking place.

So yes, I believe a single multiple will be faster than any empty function that takes a single parameter.


------

Shop for the Lowest Price!
Then, Check a Reseller's Rating Before You Purchase!

[edited by - aNonamuss on May 1, 2002 1:07:57 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by echeslack
[quote]Original post by davepermen
NEVER USE MAKROS.. bether use templates if you really need that..


why would you say that? just because it is possible to introduce problems using macros doesn''t mean you shouldn''t use them! macros can be very useful. If you don''t want to use them that''s fine, but you shouldn''t discourage other people from learning how to use them (and correctly) just because you don''t like them. Obviously you know some of the problems that can arise from using them, but it is possible and, once you know how, easy to avoid these problems. macros were invented for a reason, after all.

ewen



okay..
dont use them for typedefs, dont use them for fast inline functions
use them where you have use for them (like preventing multiple includes, knowing the line,filename,functionname etc for logging) and such

but DONT use them for functions, there is NO need on todays compilers inline functions are as fast. and they work always correct.

if you know c++ as a whole (including macros), you know where they are useful and where they are really dangerous..
and i''m not talkin about double-incrementations..

there are enums, there are templates, there are typenames, there are const etc, all features preventing making faults you don''t want.. macros can be done as well by searching for the text and replacing it manually.. means they affect ANY text..

the most useful feature is the # and ## for string generations and string concatenations for some funny thingies..

but not using macros does not mean more to write (except writing a longer replacement for the macro, okay) but means making sure everyone understands whats written there and can use it without needing to know what it is..

take the sqr macro.. say someone is assuming its a fully functional function, and calls it with the increment..
it will take possibly hours to find the bug..




for the "sqrt(void)"
first: not _every_ compiler is intelligent enough to get it away with normal settings (yesyes, even vc6 in release build will not do it completely..)
even if its simply float sqrt(float) { return 0.f; } it will ask for a push and a pop in inline-version if the compiler does not "unroll" it really (and sees he does not need to push the stuff on the stack)
and what the original statement was, is:
a function call takes much more time even if the function does not do anything than the a*a will, wich is true simply because function calls kill the stream of data, as you have to jump around in code..

if anyone is interested, i have a pretty fast approximation to sqrt and 1/sqrt (useful for normalizing vectors)

but you have to say please to get it

"take a look around" - limp bizkit
www.google.com

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:

cause math don''t like ifs and elses (or have you seen them yet in formulas in school?)



Yes, the Kronecker Delta:

d(ij) = { (1, if i=j), (0, if i!=j) }

Can be used to specify things even as simple as your identity matrix (and things much more complex).

http://mathworld.wolfram.com/KroneckerDelta.html

Share this post


Link to post
Share on other sites
okay.. never say never, right?
but in normal math (means up to calculus and everything) you normally don''t touch any functions with an if in (well.. abs(x), yeah, the big exception..)

and using if/else in functions is never that fast cause you kill the streaming structure of the function.. (and using some while(blah) { if(blahblah) do else do } is the most stupid approach for stuff like sqrt(x), or sin(x) etc..)

"take a look around" - limp bizkit
www.google.com

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by a person
Anonymous Poster, you really dont understand what you are saying. doing absolutly nothing is not the same as calling a function which does nothing. we were discussing calling a function that does nothing vs a multiply. you are merely erasing the function call from existence, and the compiler never even sees the call. you are not being clever, but rather ignorent of things.

so i guess that makes it
#define AP 0
heh, could not resist.

btw, AP, that is a GREAT optimization technique. you should write an article to gamedev on it.

<SPAN CLASS=editedby>[edited by - a person on April 30, 2002 12:51:16 AM]</SPAN>


oh, i know exactly what im doing. i was just pointing out that a function call can really be made to do nothing, thus countering saispete''s comment..so, in fact, it would be faster than a multiply, even if it did nothing.. : )

and ive got better things to write articles on besides being a smartass developer..dont have time now been putting in well over 80 hours a week to get our e3 demo done and polished..

Share this post


Link to post
Share on other sites