1
\$\begingroup\$

If the game devs add CORDIC sin cos calculation to their games, their games will have much better FPS. Why do they use normal sin cos function (e.g. Math.sin) instead of CORDIC?

\$\endgroup\$
  • 5
    \$\begingroup\$ 1) sin/cos aren't usually a very big bottleneck since usually they get converted to matrices and quaternions early on (if at all) and aren't calculated per-vertex. 2) hopefully your compiler will generate the x86 fsin/fcos opcode and you won't have to implement CORDIC yourself. \$\endgroup\$ – Jimmy Jul 16 '17 at 15:21
  • 1
    \$\begingroup\$ @Jimmy you might as well post that as an answer. \$\endgroup\$ – Tyyppi_77 Jul 16 '17 at 15:26
  • 2
    \$\begingroup\$ Related: stackoverflow.com/questions/15417482/…; summary: if you have a hardware FPU (i.e. any computer since the 1990s) CORDIC is not actually faster at all. \$\endgroup\$ – Maximus Minimus Jul 16 '17 at 15:48
  • 1
    \$\begingroup\$ I upvote this, although a different question then the usual there is nothing against the rules here afaik. A bit too technical for most and more of a complaint then a question perhaps, altering the question or just a good answer could provide some insight into the subject which is probably useful for some. I do like to see some proof of AAA FPS titles using SIN/COS instead of CORDIC. So put in a bit more effort please MCCCS. \$\endgroup\$ – Madmenyo Jul 16 '17 at 20:31
  • 7
    \$\begingroup\$ Sentences like "their games will have much better FPS" are usually what leads to microoptimizations and false-optimizations. \$\endgroup\$ – Bálint Jul 16 '17 at 22:44
8
\$\begingroup\$

Because on the x87 (the x86's FPU) the fsin, fcos and fsincos instructions are much faster than software CORDIC.

On other architectures such as PowerPC and ARM you usually can rely on an optimized implementation within the standard c library, the performance cost in normal use cases is still so minimal to not be worth the time re-implementing.

fsin or fcos timing (latency cycles) on x86:

  • Pentium (1st generation): 65 to 100 cycles typical, 16 minimum
  • Pentium II and Pentium III: 17 to 97 cycles
  • Pentium 4: approx 180 cycles
  • Pentium M: 80 to 100 cycles
  • Atom: around 260 cycles
  • Nehalem: around 100 cycles
  • Sandy Bridge: 20 to 100 cycles
  • Ivy Bridge: 21 to 78 cycles
  • Haswell: 71 to 100 cycles
  • Broadwell: 70 to 100 cycles
  • Skylake: 53 to 105 cycles
  • Knights Landing (Xeon Phi): 40 to 250 cycles
  • K7: 90 to 100 cycles
  • Jaguar: 4 to 44 cycles
  • Bobcat: 4 to 44 cycles
  • Ryzen: 11 to 60 cycles

Timing source: http://www.agner.org/optimize/instruction_tables.pdf

When calculating CORDIC extra delays are added due to FPU pipelining latency, counting the cycles of fadd and fcmp operations does not give a true picture of the time CORDIC takes on a modern CPU due to all the pipeline stalls involved in the CORDIC algorithm.

Even on x86 CPUs where fsin takes 260 cycles (worst case) it would still take much longer looping over the CORDIC algorithm for the same reasons: the FPU is slow.

If performance of sin/cos is critical, and in those case usually precision is not as important, a lookup table is much faster than even a single loop of CORDIC.

A small 16bit x 128 entries quarter-sine interpolated table gives more than enough precision for practical video game uses.

\$\endgroup\$
3
\$\begingroup\$

First of all, the FPS wouldn't be better. Most modern games are bottlenecked by the GPU mostly and are pretty OK with the CPU (often times only reaching a CPU usage of around 50% or less).

Second, CORDIC is designed to be precise and easily implementable in the hardware. The sinus method (cosinus is basically a sinus with an offset) in most languages use the sinus method from the x86 architecture or other similar alternatives. It cuts corners using smart bit trickery (similar to the inverse square root formula from Quake) instead of calculating the value in the normal way, thus loses precision in favor to speed.

Even if the hardware isn't strong enough to calculate the amount of trigonometric functions the program needs, it's easier and faster to use lookup tables than to implement a different algorithm.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.