According to the advertisements of the late eighies, you could find RAM having an access time ranging from 120 to 80 ns (150 to 210 cycle times).
Which means essentially up to 6 million full access operations per second.
A 386SX-25 could execute a typical register to register instruction in 2 cycles of 40 ns. Would it (and all the PC of the era) need to add wait states that dropped its effective speed to 4 to 6 MHz in order to align to those memory cycle times?
True for complete random access, ignoring page mode. Consecutive access like usually with program, will use page mode, were only the first access needs to be full length.
Then what is the point of having a 3 stage pipeline
Erm, according to intel documentation it's 6 stages (*1)
if you had to wait years before memory could catch up, even assuming a 32 bits data bus (386DX) to fetch instructions in a single word?
Uh-Oh. Timing is way more complex than just counting cycles. There are (at least) two actors, Cpu and memory. For the CPU basic considerations are
Basic access time for a 386 type CPU for memory is always two bus cycles (= two clock cycles), named T1 and T2 (*2)
The 80386 offered a pipelined addressing mode. When an address was acknowledged during the first access cycle (T1) by asserting /NA (Next Address), then the next address was already supplied during T2 of the previous access. So usage of an external Essentially extending access time to three cycles.
The 386DX does 32 bit instruction fetch, so four bytes in one cycle, a 386SX does two.
The 386, like all x86, has its BIU (Bus Interfac Unit) running asynchron to the EU (Execution Unit). This allows the Prefetch Unit to fetch instructions independent and ahead of time.
The Prefetch Unit maintains a 4 word (16 byte) queue. This is not a synchronous pipeline stage, but a real independent prefetch. The PU issues a read request toward the BIU every time there is room in the queue for (at least) one word (32 bit). This request got lowest priority, thus will be executed whenever there is no other task to do. Essentially using all free cycles to keep the queue topped up
For RAM there comes at minimum the difference between full cycle access, which is 150 ns in your example and CAS only access (page mode) access which can be used for consecutive access, getting it down to 80 ns.
For program execution this works as follow:
A 25 MHz 386 got a 40 ns cycle time, thus two cycles give 80 ns for access. So with 150 ns cycle time RAM two TI (wait cycles) are needed for any random access, while only one is needed for consecutive (page mode) access (*3)
Address pipelining stretches the time between address output and data read to 120 ns, thus reducing the need for a wait state to only random access and only a single TI. this is especially noteworty for 386SX boards, as the do a lot of consecutive access.
32 bit (386DX) access acts faster than needed by fastest operations, while 16 bit (386DX) even acts faster than needed.
The mentioned RR type move is two bytes long an takes two cycles to execute. Without wait states the same two cycles fetching two bytes (386SX) or four bytes. So for this (narrow) example the 386DX BIU is fetching instructions twice as fast as the EU can handle them. It's rather the fast instructions with long encoding that may slow execution - but even there it levels out rather fine.
The BIU can insert code fetch whenever the PU has room (i.e. requests a word) and no otehr access (usually data) is pending.
Being a true asynchronous word wise queue, it doesn't act like a fixed function pipeline stage handling instructions, but more basic (and abstract) as a dynamic buffer on word level, thus working more efficient than instruction based read ahead.
With all of this combined the 386DX executes in a near wait less manner up to 20-25 MHz from standard (fast) page mode RAM. Only for speeds past 20-25 MHz a cache could add performance.
Conclusion: A 386DX could come close to it's maximum performance with 80 ns RAM (and a well designed board).
And Now For Something Complete Different
The VGA standard was introduced in 1987, according to Wikipedia. How a computer of the era could write in a graphic framebuffer of 150K in less than 200ms, then?
There are a few misconceptions here
- VGA is not main memory, it is I/O bus, aka ISA-bus.
- ISA Bus is limited to 16 bit (usually with wait states)
- ISA Bus is limited to 6(8) MHz (without overclocking that is *4)
- VLB with faster (and 32 Bit) access wasn't introduced until ca. 1993.
- To make it worse, genuine VGA is limited to 8 Bit transfers
last but not least,
- VGA at that time meant 320x200 and fits in 64 KiB :))
Maximum thruput on 8 MHz 8 bit bus is 8 MB/s (*5) quite enough for 60 frame copies with 64 KiB each. Double buffering could enable a smooth display. Still it would occupy >50% CPU time to frame transfer, leaving not much time to calculate the next frame.
And this is essentially were the most basic misconception lies: The assumption of screen operation in terms of full frames submitted. Games that rely on frame redraw, like DOOM, could simply not display a full screen rendering on a 386. It needed a fast 33 MHz 486 and VLB or PCI VGA cards to even do 320x200 in all beauty.
Long story short: Games were a complete different beast back than then now - almost as much as they were different from an Atari 2600. Similar 'high' resolution usage in any other program. So never 'backport' today's approach and usage of computers back to that time.
*1 - Not arguing here, just referencing to page 2-1 of the 80286 Hardware Reference Manual stating "The six-stage pipelined processing of the 80386 ..."
*2 - Inserted wait cycles (TI) are essentially repeated T2 cycles.
*3 - Although that is rather tight and depends a lot on address decoding, multiplexing and forwarding logic. Essentially a case were slower clock 386, like 20 MHz, will be faster than its 25 MHz brother.
*4 - This is also why it was so important to get a board that allowed to increase I/O-clock past 8 MHz
*5 - Lets ignore for this that default was 6 MHz and many boards inserted by standard (and default) wait states. Similar ignoring possible page flipping and alike.