VBGamer |
|||||||||||||||||||||||||||
Ok, going to clear some things up. Adam Hoult (1 reply, 0 views) (2000-Aug-3) Well there isn't much point in sending the code, it's fairly simple
10,000,000 lookups using COS took 2.6 seconds (SIN was slightly slower at 2.8 seconds)
10,000,000 reads from a LUT took 170ms
(both returning Floating Point Values (singles))
Think about it logically. Calling a Function, which performs mathematical equations to return the Cosine of a value (where you possibly also have to convert your angle to radians first, and then possibly back to degrees when it's returned) where every value along the way is checked for errors, or a simple READ operation ?? I'm sure that there must have been something wrong when you tested it out, because common sense says (and the actually internal workings of ANY cpu) that the latter would be far quicker. (I'm not saying anything about your coding abilities here, or even that you did anything wrong, so please don't take that the wrong way)
"the REALLY good lookup tables don't use degrees OR radians, they use just values from 0 to 256. Then you just use, for instance, 64 as "90 degrees" everywhere in your code. This allows you to use bitshifts instead of divides or something to that effect -- I'm not sure"
While this is true in C++ it makes no difference at all in VB, calls to External Bitshift DLL's have far more overhead than a simple divide (if you're a real optimisation freak, you should be using Multiplies anyway, not divides), and a bit shift will only allow you to move from 64 to 32 etc. The compiler will NEVER optimise to this degree of accuracy, so that statement is actually not true. (Sorry to contradict you, i really hate doing that to people =/
There is actually a distinct accuracy disadvantage to using a 256 element LUT. So in all cases where using a Cos/Sin LUT where you don't need floating point accuracy, in VB you should always use a degree based table (i.e 360 elements, or more if you REALLY need them). In ALL other cases you should use a COS/Sin call. (see below, why you may as well ALWAYS use Cos/Sin with certain optimisations turned on)
Now, there IS an exception to this rule, By turning on "Remove Floating Point Error Checks" in the advanced optimisations properties, both using Cos and using a LUT will be performed at identical (or almost) speeds.
We now perform 100 million calls to both (as opposed to only 10 million in the previous example);
100,000,000 calls to COS took 1,142 ms
100,000,000 reads from LUT took 1,132ms
So you can see just how much error checking is going on here (100 million calls to COS previously took 26 seconds, and now only takes 1.1 seconds). However it's not totally advisable to do this, and can have adverse affects on some platforms, so it's your choice. Take it or leave it =) If your testers report that it works perfectly well, with these checks removed, on a varied set of platforms then go for it. (FYI removing all the other checks will also speed this up even further, down to about 400ms each, for 100 million itterations)
All these tests are performed on a standard, 450mhz Intel Pentium ]|[ (not overclocked) using a compiled EXE with or without optimisations as stated above.
So in short, Jack : You are absolutely right in your use of Cos/Sin instead of LUT's (in fact I would never bother using a LUT for cos/sin at ALL in VB (or C++ to be honest with you because i need the accuracy)) But the statement that reading from memory is slower than calling an external function to perform a mathmatical task seems .. strange to say the least =) (Again don't take that the wrong way, I only mean that something really Screwy must have been going on at the time, perhaps the LUT was stored in Virtual Memory =)
Anyway hope this helps clear some things up, for anyone reading.
Adam
|