3 comments

  • garganzol4 hours ago
    100x speed improvement of math operations by 8087 is not an overestimation. The difference for apps relying on math was crazy back then. I experienced this first-hand on my 80286 machine, where it was 3-second vs 300-second calculation results.<p>One neat feature of 8087 instruction set is that it can be interspersed with x86 instructions in the code stream, giving you a simultaneous access to two processor chips working in parallel. This combo forms a real asymmetrical multi-processor system with certain opportunities for hardware-assisted code parallelization. If a thoughtful instruction scheduling is used, floating operations executed by 8087 work in parallel with the usual integer x86 code.
    • mgaunard1 hour ago
      Any modern processor has different execution ports specialized in different things and replicated a different number of times, and all of them can execute instructions in parallel.<p>It schedules to these transparently for you, that&#x27;s known as superscalar execution. To maximize occupation, out-of-order execution and simultaneous multithreading are used.
      • Sharlin27 minutes ago
        Sure, but this was five (or six?) generations before actual superscalar x86 processors.
  • cogman104 hours ago
    x87 is such a weird architecture. It was designed the same way you&#x27;d design a chip for a scientific calculator. Heck, It&#x27;s almost a perfect fit for an HP RPN calculator.<p>But for a compiler to target, it&#x27;s just so painful. It&#x27;s so different from almost all other ways CPUs work. There&#x27;s a reason both CPU and compilers prefer to avoid x87 when possible and use regular SIMD (SSE&#x2F;AVX) instead.<p>Also, the arbitrary &quot;Oh, and the registers are 80 bits wide&quot; is also just one of those weird &quot;Where did that number come from?&quot;.
    • jcranmer3 hours ago
      &gt; But for a compiler to target, it&#x27;s just so painful. It&#x27;s so different from almost all other ways CPUs work. There&#x27;s a reason both CPU and compilers prefer to avoid x87 when possible and use regular SIMD (SSE&#x2F;AVX) instead.<p>The x87 ISA is essentially a one-address stack-based ISA (so unlike a pure stack ISA, you can reference another value on the stack without having to introduce something like a dup instruction). Which honestly isn&#x27;t particularly painful to work with for a compiler; it&#x27;s not usual, but there are other ISAs that are also stack-based (the JVM bytecode is the one that most immediately comes to mind).<p>The <i>actual</i> weirdness of x87, what makes all the compilers run away from it, is that the only values you can have on the stack are 80-bit extended-precision types. But people don&#x27;t use those types in their code, they use 32-bit and 64-bit single and double precision, and compilers largely implemented these types by pretending that the x87 just used those value sizes in the first type (the only ones to actually get it correct that I&#x27;m aware of are Java&#x27;s strictfp and Intel&#x27;s icc, although the latter is merely just correctly implementing FLT_EVAL_METHOD==2). The end result is that compilers caused code to have essentially random and largely uncontrollable precision changes, which pissed a lot of users off, and the SSE units having regular scalar proper single and double precision types made it easier for compilers to switch to that rather than introducing the proper sequences to compile for x87.
      • ack_complete55 minutes ago
        There is a significant difference between a stack-based ISA and a stack-based bytecode. In bytecode, it&#x27;s fine or even a requirement to empty the stack between loop iterations. The JIT will then enregister variables across the loop as appropriate.<p>With x87, however, that causes extra overhead from loads and stores that&#x27;s best avoided. Unused stack space can be used to cache frequently used variables, but as operations must use ST(0) as one parameter, FXCH instructions must be used to swap around variables. Matching the x87 stack state on entry and exit of the loop is tricky and compilers historically have had trouble doing it. Different FPUs also differed on the efficiency of FXCH so there were often situations where a particular arrangement would double the speed of a routine on one CPU model and halve it on another.
    • Sharlin23 minutes ago
      There&#x27;s also the fact that for all intents and purposes, the real floating-point unit of any x86 in the last 20 years is the SIMD unit, and legacy x87 instructions are emulated on top of that.
    • em3rgent0rdr4 hours ago
      80-bit wide registers isn&#x27;t really arbitrary if you consider that the bulk of the floating point number is a 64-bit significand (and the signifiand ALU makes sense as power-of two) and that you don&#x27;t need as many bits for exponent (it would be wasteful to go to the next power of two up). Memory is stored as 8-bit bytes as the lowest addressable unit, and so the question would be how many extra bytes the number should take, and 80 bits is a nice integer number of 10 bytes.
    • matja4 hours ago
      &gt; Also, the arbitrary &quot;Oh, and the registers are 80 bits wide&quot; is also just one of those weird &quot;Where did that number come from?&quot;.<p>One of the features that was advertised (mentioned in the iAPX 86, 88, 186 Microprocessors Part II book (July 1984)) was the ability to do exact arithmetic on integers up to 2^64, which is possible due to the 64-bit mantissa used in the 80-bit format.
      • mortja3 hours ago
        So in a sense the 8087 was the first 64 bit CPU?
        • matja3 hours ago
          I wouldn&#x27;t say so, because it was a co-processor: e.g., it depended on the 8086 to even generate addresses for memory operations.<p>I think the IBM 7030 Stretch CPU (from 1964) would be a likely contender for being one of the first 64-bit CPUs.
        • kens3 hours ago
          The Cray-1 (1976) was probably the first 64-bit CPU.
          • kragen3 hours ago
            <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;64-bit_computing#64-bit_data_timeline" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;64-bit_computing#64-bit_data_t...</a> names Stretch from 01961 as the first natively 64-bit CPU, but maybe there are some that are even older?
            • kens2 hours ago
              I forgot about the IBM 7030 Stretch (1961), which was also 64 bits. The NORC (Naval Ordnance Research Calculator) (1954) had 16 decimal digits, which is sort of 64 bits.
    • kens3 hours ago
      I&#x27;ve looked at some early calculators and they are a whole different world of weirdness. They used decimal arithmetic (BCD) because it&#x27;s a lot easier than converting between binary and decimal. The first calculators were serial, with a 1-bit adder and shift registers and bits constantly in motion. The Sinclair Scientific calculator used TI&#x27;s strange 4-bit architecture along with terrible algorithms.
  • kens5 hours ago
    Author here for your 8087 questions...
    • bonzini4 hours ago
      That&#x27;s a really vertical microcode. It looks more like a specialized assembly than microcode. I guess it makes sense, since the algorithms are so complex and executing one microinstruction per cycle (is that correct?) already provides almost an order of magnitude performance improvement.
      • kens2 hours ago
        Yes, it&#x27;s one microinstruction per cycle, except there is a 1-cycle delay for branches, adds, and shifts. And some micro-instructions loop, so they can take a bunch of cycles.
    • pechay2 hours ago
      Great work! I love to read your articles.<p>I&#x27;m curious to know - you say Intel&#x27;s 8087 emulation code was a bit of a lump at 16KB, do you know if it emulated the 8087 microcode state machine or did it use a different strategy?
      • kens2 hours ago
        I think the emulation code was a rewrite in 8086 assembly language. An 8087 microcode emulator would be slow and difficult. One of the Opcode Collective people is looking at the emulator now, so there may be more details later. Intel claimed that the emulator completely and exactly duplicated the 8087 functionality, so it would be interesting to see if it is 100% accurate or if they missed any corner cases.
    • agumonkey2 hours ago
      no questions, just thanks