I know that x87 has higher internal precision, which is probably the biggest difference that people see between it and SSE operations. But I have to wonder, is there any other benefit to using x87? I have a habit of typing -mfpmath=sse
automatically in any project, and I wonder if I'm missing anything else that the x87 FPU offers.
SSE is a process or technology that enables single instruction multiple data. Older processors only process a single data element per instruction. SSE enables the instruction to handle multiple data elements.
Up to eight floating point arguments can be passed in XMM registers %xmm0–%xmm7. These registers are used in the order the arguments are listed. Additional floating-point arguments can be passed on the stack. A function that returns a floating-point value does so in register %xmm0.
For hand-written asm, x87 has some instructions that don't exist in the SSE instruction set.
Off the top of my head, it's all trigonometric stuff like fsin, fcos, fatan, fatan2 and some exponential/logarithm stuff.
With gcc -O3 -ffast-math -mfpmath=387
, GCC9 will still actually inline sin(x)
as an fsin
instruction, regardless of what the implementation in libm would have used. (https://godbolt.org/z/Euc5gp).
MSVC calls __libm_sse2_sin_precise
when compiling for 32-bit x86.
If your code spends most of the time doing trigonometry, you may see a slight performance gain or loss if you use x87, depending on whether your standard math-library implementation using SSE1/SSE2 is faster or slower than the slow microcode for fsin
on whatever CPU you're using.
CPU vendors don't put a lot of effort into optimizing the microcode for x87 instructions in the newest generations of CPUs because it's generally considered obsolete and rarely used. (Look at uop counts and throughput for complex x87 instructions in Agner Fog's instruction tables in recent generations of CPUs: more cycles than in older CPUs). The newer the CPU, the more likely x87 will be slower than many SSE or AVX instructions to compute log, exp, pow, or trig functions.
Even when x87 is available, not all math libraries choose to use complex instructions like fsin
for implementing functions like sin()
, or especially exp/log where integer tricks for manipulating the log-based FP bit-patterns are useful.
Some DSP algorithms use a lot of trig, but typically benefit a lot from auto-vectorization with SIMD math libraries.
However, for math-code where you spend most of your time doing additions, multiplications etc. SSE is usually faster.
Also related: Intel Underestimates Error Bounds by 1.3 quintillion - the worst case for fsin
(catastrophic cancellation for fsin
inputs very near pi) is very bad. Software can do better but only with slow extended-precision techniques.
EOF
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With