views:

486

answers:

8

Hi. I wish to make a cosine table at compile time. Is there a way to do this without hard coding anything?

+11  A: 

Why not hardcode it? I am not aware of any changes in the result of the cosine function that they are planning, well not for another 100 years or so.

leppie
Long ago similar frivolous assumption led to Year 2000 problem :)
Kirill V. Lyadvinsky
This is a mathematical constant so it's not going to change, never! What could change however, is the units. Maybe 200 years from now, 500 will be the right angle. But even if that were to happen, it has no bearing on whether the values are hard-coded are generated at runtime.
hasen j
Because it would lead to a long and tiresome code with a huge table inside.
martiert
@martiert: it sounds like you are doing something wrong. How can the code be tiresome from a look to an array? Or are you just plain lazy?
leppie
@martiert - As part of your build process, just make a program that automatically generates the lookup table for you. That way, you get it at compile time, but you don't have to write it by hand, and you get the accuracy of automation.
Chris Lutz
+4  A: 

You could generate it with any scripting language you liked and include the result. Use make to have the scripting language do its thing anytime you change the source. It's hard coded to C but not to you, really.

Ollie Saunders
http://codepad.org/0lUu8JIZ
hasen j
@Hasen J: Post this code as an answer and I'd upvote it.
Daniel Pryden
+7  A: 

With C++, you can use templates metaprogramming to generate your lookup table at runtime.

Now, here is a standard C trick that may or may not accomplish what you want.

  1. Write a program (say, cosgen) that generates the cosine table C statement (i.e., the code that you desire).
  2. Run cosgen and dump the output (c code) to a file, say cos_table.c
  3. In your main program, use a #include "cos_table.c" to insert the table where you want.
miko
It's C, to go on the CELL, and not C++
martiert
You should `#include "cos_table.h"` that _declares_ the `cos_table` array, rather than including a new definition for every file that uses it.
Chris Lutz
+1  A: 

With the magic of computers, the apparently impossible becomes possible:

#include <stdio.h>
#include <math.h>
#define MAX_ANGLE 90
double kinopiko_krazy_kosines[MAX_ANGLE];
int main ()
{
    int i;
    for (i = 0; i <= 90; i++) {
        double angle = (M_PI * i) / (2.0*90.0);
        kinopiko_krazy_kosines[i] = cos (angle);
        printf ("#define cos_%d %f\n", i, kinopiko_krazy_kosines[i]);
    }
}

http://codepad.org/G6JTATne

Kinopiko
That looks like runtime to me :-).
Douglas Leeder
Better now??????
Kinopiko
Nothing personal, Kino, but I wouldn't use any variables named `kinopiko_krazy_kosines` You might want to find a new letter to use if you're going to use that kind of alliteration in the U.S.
Chris Lutz
Does having three k's really worry people in the US that much?
Kinopiko
+1  A: 

I'd create a hard-coded lookup table - once with a scripting language - but I'm not sure it'll be faster than just using the standard math library.

I guess it depends on the size of the table, but I would suspect getting the FPU to do the calculation might be faster than accessing memory. So once you've got your table solution, I'd benchmark it to see if it's faster than the standard function.

Douglas Leeder
The usefulness of such a table depends a lot on the platform your run on. Most embedded and/or lower-power CPUs are much faster at accessing memory than they are at doing floating point calculation (especially sine/cosine which may not be native commands).
Joachim Sauer
That is true - I assume the platform, if not specified, is Windows x86.
Douglas Leeder
Assuming Windows in combination with the GCC preprocessor? Unusual assumption there.
MSalters
+9  A: 

I am not convinced that precalculating a sine table would result in a performance improvement. I suggest:

  1. Benchmark your application calling fcos() to decide whether it's fast enough. If it is, stop here.
  2. If it really is too slow, consider using -ffast-math if it is acceptable for your usage.

Lookup tables, particularly large ones, will increase the size of your program that needs to be held in the CPU cache, which reduces its hit rate. This in turn will slow other parts of your application down.

I am assuming you're doing this in an incredibly tight loop, as that's the only case it could possibly matter in anyway.

If you actually DID discover that using a lookup table was beneficial, why not just precalculate it at runtime? It's going to have hardly any impact on startup time (unless it's a huuuuuge one). It may actually be faster to do it at runtime, because your CPU may be able to do sines faster than your disc can load floats in.

MarkR
+2  A: 

Since you're targetting Cell, you're probably targetting the SPE's? They do have proper FP support, vectorised in fact, but do not have large working memories. For that reason it's in fact a BAD IDEA to use tables - you're sacrificing a very limited resource.

MSalters
I know, but memory is not a problem in my application. And I found out that 80% of the time is used in calling the cos() function.
martiert
Are you by any chance using `double cos(double angle)` ? SPEs have very poor performance with double-precision FP.
MSalters
A: 

Wave tables are the way to go. You can hard code it as suggested, or run it during application start up.

James Morris