← Back to context

Comment by Const-me

5 hours ago

I would add than SSE1 and SSE2 are now required parts of AMD64 instruction set. All 64-bit PC processors are required to support them both. For that reason, modern compilers are ignoring x87 FPU when building 64-bit binaries. Instead, they compile all float and double arithmetic into SSE1 and SSE2 instructions, respectively.

Take a look at the micro-architecture levels. x86-64-v1 contains all the instructions that the original AMD64 and compatible Intel CPUs supported. v2 is all the SSE levels, v3 is AVX and AVX2, v4 is AVX-512.

https://en.wikipedia.org/wiki/X86-64#Microarchitecture_level...

  • The wiki says:

    "Additional XMM (SSE) registers: Similarly, the number of 128-bit XMM registers (used for Streaming SIMD instructions) is also increased from 8 to 16...

    "The original AMD64 architecture adopted Intel's SSE and SSE2 as core instructions."

    https://en.wikipedia.org/wiki/X86-64

    This wansn't v2?

    • x86-64 mandates SSE2 as a minimum requirement because it uses the SSE registers in the ABI for implementing float (which requires SSE) and double (which requires SSE2) arithmetic. (The x87 unit, which is what the 32-bit x86 ABI uses, can only do extended-precision arithmetic, which causes a whole heap of problems). Because it's so thoroughly integrated in the ABI, v1 has to have a min-SSE2 requirement.

      Subsequently, there were additional instructions added in SSE3, SSSE3, SSE4.1 and SSE4.2, which are all incorporated into the v2 ISA level (along with a few other instructions). Then all of these instructions were given 256-bit variants in AVX, and AVX2 adds some more vector instructions; these are incorporated into the v3 ISA level. And then along comes AVX-512 and naming just becomes a podge at that point...

    • Not sure what your question is. I dont see any contradiction with the parent comment. SSE went to version 4.2 (it gets complicated in the numbering and even naming). Only 1 and 2 were included in the base 64-bit ISA.

Extended double has some niche and quite useful for its application properties. You can for instance simulate 128 bit floats more easily with it.

Which is not to say that they are necessarily auto-vectorizing. You know wassup when you see vaddsd instead of vaddpd. And ideally you'd use AVX-512 to saturate a modern cache line if you can afford to drop support for the older devices.

Compilers like GCC and Clang treat C's "long double" type by default as 80-bit wide and result in x87 generated code. This can be overridden to use either 64-bit or 128-bit floating point values.