• Advertisement

Archived

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

Sine and Cosine: Lookup or Realtime?

This topic is 5989 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is it still feasible with modern computers to build sine and cosine tables during the initialization process and use those lookup tables instead of calling the sin() and cos() functions realtime? Does it still have a reasonable increase in performance?

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
(bump)

Good question. I was wondering the same thing a few days ago.

Should be easy to test, though. I''ll throw something together later today or tomorrow and post the results, unless someone knows off the top of their head.



Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Why don''t you write a test program and post it? Then different people with different levels of computers can test it out and see how much of a difference it makes.

Share this post


Link to post
Share on other sites
Why don''t you write a test program and post it? Then different people with different levels of computers can test it out and see how much of a difference it makes.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Ran some test code. Urm... the code is on my other machine, I''ll see about posting it later, but I''ve included some pseudocode here.

Machine: PII 400 MHz, using the Borland free compiler

Pseduocode:

class Timer {};
const largeNum = 100,000


Stuff defined outside the test cases. The proggy was a console mode program so the Timer class includes a std::cout inside of the destructor to spit out the elapsed time in ms.


//Test 1
Timer test1; // constructor inits the timer

double sinTable[90];
double d = 0.0;

loop (i < 90)
sinTable = sin(i*); //*converted to radians

loop (largeNum)
loop (i<90)
d += sinTable[i];

end timer


Test 1 inits an array of sin values in 1 degree increments (prolly should be 0-90 instead of 0-89, but the error is minor)

Then it performs 9 million array accesses. Elapsed time approx 300 ms. I suspect that a compiler using the M$ run-time (msvc++ or mingw) would be faster, but I haven''t run it there.



//test2
Timer test2; // constructor inits the timer

double d = 0.0;

loop (largeNum)
loop (i<90)
d += sin(i);

end timer;


The second test was calling the sin function 9 million times. There was a slight difficulty since the sin function takes a radian angle instead of a degree angle, but since the results (d) did not matter, I just passed the degree angle as if it were radians.

I know adding in an extra const multiplication in the inner loop would slow things down a little, but I did not try using a double for the inner loop variable (also slow I expect).

elasped time: approx 2600-2700 ms


So there is a significant difference in speed (I got a factor of 8 or so). But then, how many sin calls do you need per frame?

For a const 33.333 frames per sec (30 milliseconds per frame) the first method gets me 900,000 sin values while the second gets me a little over 100,000 sin values. Even the slower version is *fast*.

YMMV, depending on the compiler and math library. I''ll try to post the actual code later.

Share this post


Link to post
Share on other sites
Won''t you need a rather more large table if you expect to get accurate results in your engine? There could be ''large'' errors on objects deep down in an object hierarchies with a too small LUT.
And the reason it''s going as fast as it is (with the LUT) now is probably because you''re not accessing any other memory between the sin table - thus the cache makes wonders here. Maybe you should try to run some ''random'' memory accesses in between now and then and post the new results? And, second point is, that you''re accessing the table linearly - i.e. you read a[n + 1] after a[n] and thus the data is almost always in the cache.

And then, when/if you increase the table size -> cache doesn''t work quite as well anymore, still...

Share this post


Link to post
Share on other sites
Try a short Taylor/MacLaren series of sin, one that gives you ~5 digits of accuracy from 0 to pi. You can use a little trig to get all the values of sin from that.

In certain cases the table could be faster, but the above method should be fast enough, and it doesn''t gobble up a big chunk of RAM. A page faults would cause the table method to be alot slower, and the more RAM you use, the greater the likelyhood of a page fault.



Magmai Kai Holmlor
- Not For Rent

Share this post


Link to post
Share on other sites
I had a small program that did this, and believe me, lookup tabels are faster. I can''t quite remember the results at the moment, as it is rather old, but to do something like 100,000 or 1,000,000 simple calculations, it took the Sin function about 450ms, and the lookup table just over 50ms.

That was with my compiler''s optimization turned off.

~ There''s no substitute for failure ~

Share this post


Link to post
Share on other sites

  • Advertisement