Search code examples
c#c++algorithmmathtrigonometry

What is the fastest way to compute sin and cos together?


I would like to compute both the sine and co-sine of a value together (for example to create a rotation matrix). Of course I could compute them separately one after another like a = cos(x); b = sin(x);, but I wonder if there is a faster way when needing both values.

Edit: To summarize the answers so far:

  • Vlad said, that there is the asm command FSINCOS computing both of them (in almost the same time as a call to FSIN alone)

  • Like Chi noticed, this optimization is sometimes already done by the compiler (when using optimization flags).

  • caf pointed out, that functions sincos and sincosf are probably available and can be called directly by just including math.h

  • tanascius approach of using a look-up table is discussed controversial. (However on my computer and in a benchmark scenario it runs 3x faster than sincos with almost the same accuracy for 32-bit floating points.)

  • Joel Goodwin linked to an interesting approach of an extremly fast approximation technique with quite good accuray (for me, this is even faster then the table look-up)


Solution

  • Modern Intel/AMD processors have instruction FSINCOS for calculating sine and cosine functions simultaneously. If you need strong optimization, perhaps you should use it.

    Here is a small example: http://home.broadpark.no/~alein/fsincos.html

    Here is another example (for MSVC): http://www.codeguru.com/forum/showthread.php?t=328669

    Here is yet another example (with gcc): http://www.allegro.cc/forums/thread/588470

    Hope one of them helps. (I didn't use this instruction myself, sorry.)

    As they are supported on processor level, I expect them to be way much faster than table lookups.

    Edit:
    Wikipedia suggests that FSINCOS was added at 387 processors, so you can hardly find a processor which doesn't support it.

    Edit:
    Intel's documentation states that FSINCOS is just about 5 times slower than FDIV (i.e., floating point division).

    Edit:
    Please note that not all modern compilers optimize calculation of sine and cosine into a call to FSINCOS. In particular, my VS 2008 didn't do it that way.

    Edit:
    The first example link is dead, but there is still a version at the Wayback Machine.