> IIRC, the 8086 didn't have an ALU, so the 286 sped up code A LOT
> compared to older cpus. You'd have to ask an expert like Jim Leonard,
> but the 8086 was slow at [bx+di+2] effective addresses. Code should be
> kept simple, small, and avoid unnecessary jumps.
> ...
>
> In short, optimization is an ongoing quest. You start with something,
> benchmark it, then keep retesting until you stop. Just because you
> give up doesn't mean there isn't a better, faster way.
>
> If you're truly interested in 8086 speed improvements, I would keep
> digging.

The 8086/8088's were pretty simply, and there's not a lot you can do to 
optimize for them.  There are a few things that help.

  # Use the CPU registers as much as possible
  # Minimize memory accesses
  # Minimize slow instructions (like MUL/DIV)
  # Minimize non-linear code (avoid JMPs and LOOPs and CALLs)

The last one is particularly important for speed (even though it creates larger 
programs), and it applies not just to the 8086/8088 but also applies all the 
way up to the 486.

The early CPUs (up through the 486) had something called a Prefetch Input Queue 
(PIQ).  The PIQ was basically a very simple caching mechanism that could speed 
up CPU operations considerably.  Some Virtual Machines emulate the PIQ and some 
don't.

The PIQ is a small "look-ahead" buffer that the CPU uses to pre-fetch CPU 
instructions from memory.  At the same time the CPU is processing an 
instruction, it is also "reading ahead" from memory and storing the next 
several instructions in a small buffer/cache (Queue) so it doesn't need to wait 
for a (relatively slow) memory access to know what the next CPU opcode is.  
This is a very rudimentary form of multi-tasking (the CPU is processing CPU 
instructions and reading future instructions from memory at the same time).  
The queuing algorithm is very simple and just assumes the code is linear (the 
CPU instructions are sequential in memory with no JMPs or CALLs or LOOPs).  
When an instruction causes the code to jump to a non-sequential memory 
location, the PIQ must reset the buffer/queue and start from scratch which 
slows things down.

As the CPUs increased in power and speed (8086->286->386->486) the size of the 
PIQ increased but it still worked the same way.  Eventually the PIQ became 
redundant and inefficient since other mechanisms like multi-level caches, 
pipelines, branch prediction, etc. were invented and became more sophisticated. 
 The PIQ was removed entirely in the Pentium-class CPUs.

Optimization is always CPU (at least CPU class and/or CPU manufacturer) 
specific.  What you would do to optimize for a later CPU (even for a 286) 
wouldn't necessarily help on an 8088, and may in fact make it worse (assuming 
the code will even work on an 8088, which modern code usually doesn't).

Another interesting thing about the PIQ is that measuring the size of the PIQ 
is the only way I know of to reliably tell whether the CPU you are running on 
is an 8086 or an 8088.  Those two CPUs are so similar that you can't really 
tell them apart programmatically.  I know some people have tried by attempting 
to measure processing speed, but with all of the clock-rate options that were 
available you really can't tell (at least not reliably) using the processing 
speed.

Measuring the size/presence of the PIQ is also one of the tests you can perform 
to see if you are running inside a Virtual Machine or not.  If the virtualized 
CPU is a 486 or less and the PIQ either doesn't exist at all or isn't the 
correct size, you can assume you're running on a virtual CPU. 


_______________________________________________
Freedos-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freedos-devel

Reply via email to