Skip to main content
GameDev.net gamedev.net
🔒 Locked

Expensive

Started by AdamGL Sep 24, 2006 at 4:45 PM 15 replies 2.2k views
Original Post
AdamGL
AdamGL
This is a short question. Which is more CPU expensive in C++? Trig functions like sin, or the square root function?
bi-FreeSoftware
oliii
oliii
question is moot really. In short, I would venture a guess. SquareRoot is the cheapest, if there is such thing.
Everything is better with Metal.
AdamGL
AdamGL
Thanks for the quick reply. I'm just trying to figure out the co-ordinates of a line with a given starting point, length and angle. to find the y I use sin, and to find x I can use cos or square root. I didn't know which so I based my decision on speed. So thank you very much for helping.
bi-FreeSoftware
deathkrush
deathkrush
If you are using SSE instructions, the sqrt function is faster because it's a built-in CPU instruction.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
TheAdmiral
TheAdmiral
The results of a crude test I just ran says that sqrtf() runs about 1-2 times the speed of cosf(). Here's a table of the number of calls I managed to reel out per second (along with a tiny bit of arithmetic and a call to GetTickCount inside the loop):

sinf(): 8,237,187
cosf(): 8,788,563
tanf(): 6,839,346
sqrtf(): 13,818,660
logf(): 10,090,013
expf(): 7,847,258
fabsf(): 11,340,255

(MSVS 2003, math.h, running a debug build on a dated laptop with a fair few processes going in the background)

I ran it a few times and the results above were fairly typical, varying by around two parts in a hundred. The same test with double-precision functions:

sin(): 8,038,044
cos(): 8,127,902
tan(): 6,337,740
sqrt(): 15,056,033
log(): 9,874,242
exp(): 8,055,070
fabs(): 10,719,045

The ratios remain roughly unchanged but, curiously, some of the float versions took longer. Any guesses?

I'm rather surprised that sin takes 'so much' longer than cos. I wonder if it would be faster to call cos(x - PI/4) instead.
Edit: As expected, no [rolleyes]. But the difference is small.

Don't take these results too seriously, though. The conditions are far from perfect and the test itself is poorly constructed. Nevertheless, I think it's pretty safe to conclude that sqrt is faster than the trig functions.

Regards
Admiral

[Edited by - TheAdmiral on September 24, 2006 6:06:20 PM]
Ring3 Circus - Diary of a programmer, journal of a hacker.
Zipster
Zipster
I haven't done a lot of floating-point assembly math, but isn't there an fsincos instruction that calculates both at the same time?
Rompa
Rompa
Being a pedantic fellow, I would say the answer to your original question depends on the CPU you're developing for, compiler settings such as enabling intrinsic functions, and implementations of the standard library square root and trig functions and no doubt other factors too.
Using approximations where applicable can appreciably increase performance, as can using inline asm statements for CPU and/or coprocessor specific implementations (as Zipster mentions).
For trig functions, you may wish to look at things like Pade polynomial approximations in preference to Taylor series approximations, as they are MUCH cheaper over to evaluate inside their given ranges (typically -pi/2 to pi/2). There are very good approximations for log, exp and others too, should you need them.
LorenzoGatti
LorenzoGatti
Quote:
Original post by TheAdmiral
The ratios remain roughly unchanged but, curiously, some of the float versions took longer. Any guesses?

My guess is that on your processor the double version is the "hardware" one and its adaptation to floats needs some mildly expensive conversions: zero padding of the mantissa and sign extension of the exponent on input and rounding (with range checking of the exponent) to extract a float on output.
Omae Wa Mou Shindeiru
erissian
erissian
If you're really concerned about speed, and you can always roll your own for arbitrary precision.

ie:

double mysin(double x) {    return x - x*x*x/6 + x*x*x*x*x/120;}


The expansions are:
sin(x) = x - x^3/3! + x^5/5! - x^7/7! - x^9/9! + ...
cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8! + ...

We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
smc
smc
Maybe I am missing the point of this thread, but you could trade size for speed and use a lookup table for you trig functions.
∫Mc
RAZORUNREAL
RAZORUNREAL
Quote:
Original post by smc
Maybe I am missing the point of this thread, but you could trade size for speed and use a lookup table for you trig functions.


Isn't the sse sqrt already based on a lookup table but done in hardware? I'm really not sure a lookup table would be faster than any of the built in functions, but I'm no expert.
___________________________________________________David OlsenIf I've helped you, please vote for PigeonGrape!
Darkstrike
Darkstrike
Quote:
Original post by RAZORUNREAL
Isn't the sse sqrt already based on a lookup table but done in hardware?


Umm, if the argument is saved as a binary mantissa+characteristic, then sqrt is a -- on the characteristic, so no need for any optimization whatsoever.
TheAdmiral
TheAdmiral
Quote:
Original post by erissian
If you're really concerned about speed, and you can always roll your own for arbitrary precision.

Sure you could, but I've found that optimised evaluation of a Taylor expansion only outperforms their trig function equivalents below order-four, or so, which makes them useful only for the quadratic/cubic versions ('cause linear is just silly). If you weigh in the fact that you have an expensive modulus function to call, to bring the input into localised range, you're probably losing out.

Should you be possessed to proceed in this way, however, you can use the distributivity laws to optimise
return x - x*x*x/6 + x*x*x*x*x/120;
to
return x*(1 - x*x*(1/6 + x*x/120));


Regards
Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
CTar
CTar
The square root operation is much cheaper on most x87 FPUs. According to Intel's optimization manual, on a P4, the latency for square root is (x/y means x or y, this can change depending on the type of P4):
Single precision (32 bit): 23/30
Double precision (64 bit): 40/38
Extended precision (80 bit): 44/43

The numbers for sin, cos and sincos is (x1-x2/y1-y2, means from x1 to x2 or from y1 to y2):
Sin: 160-200/160-180
Cos: 180-280/190-240
Sincos: 170-250/160-220

The throughput numbers are:
Square root single precision: 30/23
Square root double precision: 40/38
Square root extended precision: 44/43
Sin: 130
Cos: 130
Sincos: 140
mrbig
mrbig
Quote:
Original post by TheAdmiral
Quote:
Original post by erissian
If you're really concerned about speed, and you can always roll your own for arbitrary precision.

Sure you could, but I've found that optimised evaluation of a Taylor expansion only outperforms their trig function equivalents below order-four, or so, which makes them useful only for the quadratic/cubic versions ('cause linear is just silly). If you weigh in the fact that you have an expensive modulus function to call, to bring the input into localised range, you're probably losing out.

Should you be possessed to proceed in this way, however, you can use the distributivity laws to optimise
return x - x*x*x/6 + x*x*x*x*x/120;
to
return x*(1 - x*x*(1/6 + x*x/120));


Regards
Admiral


This comes to mind:
float a = x * x;
return x * (1.0 - a * (0.166 + a * 0.00833));
TheAdmiral
TheAdmiral
Quote:
Original post by mrbig
This comes to mind:
float a = x * x;
return x * (1.0 - a * (0.166 + a * 0.00833));

Sure, if you want to be safe, that's just fine.
I just figured that all but the stupidest compilers would perform those trivial optimisations, so I left them out for readability. Nevertheless, this topic is moot for reasons discussed above [rolleyes].

Regards
Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Raghar
Raghar
Quote:
Original post by AdamGL
Thanks for the quick reply. I'm just trying to figure out the co-ordinates of a line with a given starting point, length and angle. to find the y I use sin, and to find x I can use cos or square root. I didn't know which so I based my decision on speed. So thank you very much for helping.


Test it.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.