[HN Gopher] Multiple microprocessors as a single CPU (not multip...
___________________________________________________________________
Multiple microprocessors as a single CPU (not multiprocessing)
Author : JPLeRouzic
Score : 45 points
Date : 2023-12-14 09:54 UTC (13 hours ago)
(HTM) web link (forum.vcfed.org)
(TXT) w3m dump (forum.vcfed.org)
| johndoe0815 wrote:
| I hope it's ok to answer here instead of on vcfed.org since I
| don't want to create yet another account...
|
| Sun workstations did not use the dual 68000 approach to handle
| VM. The problem with the 68000 was that it didn't save enough
| information on the stack when an exception occurred (e.g. a page
| fault), so a faulting instruction could not be recovered/re-
| executed in all cases.
|
| Sun solved this by using "harmless" instructions such as "tst"
| that did non have to be recovered in case of a page fault. The OS
| could then kick in, load the contents to memory and just skip the
| failed instruction. This required changes to the compiler, e.g.
| when creating a new stack frame that would have required to
| extend the stack size. For paging, this approach would cause
| significant overhead. However, the first versions of SunOS which
| ran on the Sun 1 workstations were based on 7th Edition Unix and
| used only swapping.
|
| The 68010, used in the Sun-2 workstation, fixed the restarting
| problem by saving sufficient state to the stack, so SunOS could
| switch to an early BSD release as its basis.
|
| AFAIK, the dual 68000 approach was used by early Apollo
| workstations instead. The way I understand it is that the second
| processor was idling until a page fault occurred. The 68000 has
| an asynchronous bus which requires an explicit acknowledge
| (/DTACK) to indicate that data (e.g. from slow memory) has
| arrived. This feature was used by the Apollos - the second 68k
| would kick in while /DTACK on the first 68k was deasserted,
| handle the required virtual memory operations, and then indicated
| that the first CPU can continue working. So here, no bus error
| was indicated (which would have caused the restarting problem),
| but the virtual memory behaved like a very slow physical memory.
| Apollos were able to perform remote memory accesses to other
| machines over the TokenRing interface (which was about as fast as
| memory accesses - 12 Mbit/s IIRC), so this feature was much more
| useful for DomainOS than for early Unix systems.
| johndoe0815 wrote:
| Please note that I can't confirm that Apollo used this approach
| - the earliest Apollo workstation I know (the DN300) used a
| 68010 already. I would love to hear more details on this...
|
| I'm also not sure which approach early SGI workstations used
| (the Iris 1000 series), documentation on those is extremely
| hard to find.
| Tor3 wrote:
| There's a Motorola document about this:
|
| https://ia904706.us.archive.org/5/items/Motorola-
| Seminarsand... In there they suggest that "another bus master
| must perform this action" and that this one could be "an
| MC68000 MPU as well".
|
| I've also heard and seen the claim that Apollo workstations
| before the 68010 used this method, but it's difficult to find
| a definite source for this (though it's likely true. Every
| reference etc. to the pre-DN300 models claim 2x68000 CPU)
| eschneider wrote:
| I can confirm that the early Apollos did this. Worked on
| one back in the day.
| ThomasBHickey wrote:
| They did indeed use multiple 68K chips. In fact I have one of
| the motherboards down in my basement (sadly not operational).
| jonstewart wrote:
| This is great info. Can you elaborate or point to a link on the
| distinction between paging and swapping? I've always treated
| them as synonyms but clearly there are some differences on
| earlier systems.
| johndoe0815 wrote:
| Swapping (in the context of old Unix) is always replacing
| (copying) an entire process address space (or at least the
| non-shareable read-write segments such as .data), out to the
| swap device, or back, in one go.
|
| Paging is more advanced as it allows to keep only a part of
| the memory required by a process in RAM and contents can be
| loaded or moved to secondary storage on the granularity of
| single pages (typically 4 kB, but larger pages are also
| common nowadays). So a typical exec(2) system call in Unix
| could set up a new page table which contains no single byte
| of the executable in the beginning and then jump to the
| executable's entry point. This, in turn, results in a page
| fault, in turn, the OS can then load the requested page into
| RAM.
|
| Paging is more efficient since control/data flow analyses
| show that something similar to the Pareto rule (or 80/20
| rule) also applies to programs which are executed - 80% of
| the time, only 20% of the address range (for instructions
| and/or data) is used. With paging, the OS won't need to load
| any code or data from disk that is never used (and can load
| it on demand later).
|
| What's probably confusing is that the area reserved on disk
| for storing RAM contents (a partition or a file) is still
| called "swap partition/file". This is an old term that
| refuses to die, I guess...
| jonstewart wrote:
| So "old" swapping is taking low priority processes and
| putting all of their memory out to disk, almost (but
| obviously not quite) as though you're suspending them. Got
| it!
| johndoe0815 wrote:
| Here's an interesting discussion thread in comp.sys.apollo from
| 2003:
|
| https://groups.google.com/g/comp.sys.apollo/c/55dqpf11hEw/m/...
|
| The setup was more complex than I described, as the second
| 68000 did not simply wait for a page fault to happen but was
| executing regular (unclear if application only or also OS
| kernel) code and only handled the fault on the other CPU when
| interrupted by the MMU.
|
| Unfortunately, the only versions of Aegis/DomainOS available
| online seem to be 10.x (on bitsavers), but support for the
| "sau1" 68000-based systems (DN100/DN400/DN416) ended with
| version 9.x, so we can't have a look at the code implementing
| this feature.
|
| Interesting quotes from the thread:
|
| "The two processors were called "A" and "B" and processes could
| be marked runnable on A or on B or both. It was almost a
| multiprocessor, except that you couldn't run anything that
| might take a page fault on both at the same time." (by Jim
| Rees, who runs the Apollo archive at
| https://jim.rees.org/apollo-archive/)
|
| The answer to the following question was posted by Dave Tweed,
| a former Apollo engineer who worked on the MMU design for later
| Apollo workstations (see his resume at
| http://www.dtweed.com/resume2.html):
|
| "> Hmm. So how did CPU B know that this was needed? It sounds
| like they > weren't running the same code, after all.
|
| No, of course not. The MMU was external to both CPUs, and when
| one CPU encountered a page fault, the MMU would interrupt the
| other CPU to handle the exception.
|
| The CPUs shared the main memory, so in that sense they were
| running the same code -- e.g., there was only one copy of the
| exception handler that either CPU could run. But they were not
| lock-stepped the way the OP described. I can't even imagine how
| you'd accomplish that in general."
|
| What a fascinating rabbit hole...
| johndoe0815 wrote:
| Another not quite that interesting approach (more of an I/O
| coprocessor) was used when you put a Z80 CP/M "Softcard" into a
| (6502-based) Apple II.
|
| Steve Wozniak's floppy controller was very simple on the hardware
| side (more or less only a state machine implemented in a PROM),
| so most of the data serializing/deserializing and GCR de/encoding
| was done in software on the 6502. This was very timing-critical,
| so implementing this in Z80 code for CP/M instead would have been
| a challenge.
|
| Instead, the Z80 on the Softcard called 6502 routines to handle
| disk (and other) I/O. Usually, the 6502 is stopped when running
| Z80 code, but it had to be woken up frequently not only for I/O
| accesses, but also to ensure that the 6502 did not lose its
| register values, which are stored in dynamic memory cells in the
| (non-CMOS) 6502.
| rwmj wrote:
| Do IBM Mainframes that can fail over to a second CPU running
| synchronously with the first count?
| mr_person wrote:
| Tandem (now HPE) NonStop do something like this... Run 2
| systems in lock-step for super resilient computing. The code
| has specific instructions for validating operations by
| comparing the outputs on both CPUs
| 082349872349872 wrote:
| Originally Tandem (despite their swag coffee mugs that had
| only two handles) ran 3 systems; having an odd number made it
| easier to compare outputs.
|
| https://en.wikipedia.org/wiki/File:Tandem_Mug_with_Redundant.
| ..
| denton-scratch wrote:
| Also Stratus: Wikipedia says they were originally built
| around M68Ks. The WP article is a bit thin on Stratus's early
| products, but my vague recollection is that they used 3
| processors in lockstep, with voting to detect a faulty
| processor.
| dusted wrote:
| The DEC J-11 CPU is a single CPU that is implemented on two
| discrete chips with one taking care of control and the other of
| data paths, not exactly the same idea as using two identical
| cpu's to implement a different architecture, but somewhat
| related.
| irdc wrote:
| Not sure it counts, as it's a single 60-pin DIP module holding
| the two pieces of silicon. Indeed, one could see the J-11 as an
| early chiplet design.
| irdc wrote:
| This sounds like the way the 8087 and 8089 (look that one up!)
| co-processors worked: they snooped the instructions the 8086/8088
| CPU read from memory and then handled their own subset of the
| instruction set. That did require that they could reconstruct the
| program flow from instruction fetches, which probably became nigh
| impossible when CPUs started integrating instruction caches.
| EvanAnderson wrote:
| Saving others the trouble:
| https://en.m.wikipedia.org/wiki/Intel_8089
|
| Indeed, I'd never heard of the 8089. Now I'd like to know more
| about it.
|
| Edit: More links.
|
| https://retrocomputing.stackexchange.com/a/13815
|
| http://www.bitsavers.org/pdf/intel/ISIS_II/9800938-01_8089_A...
| colejohnson66 wrote:
| Nitpick: Only the x87 line snooped the bus and mimicked
| prefetch as it was a coprocessor that had its opcodes _inside_
| the x86 's. Specifically, any opcode beginning with 0xD8
| through 0xDF is an x87 opcode. The 8089 is different, and
| worked more like old IBM mainframes did with I/O channels; The
| 8089 had a dedicated opcode set (distinct from x86) that it
| would execute. "Jobs" (of sorts) were created on the 8086 CPU,
| then handed over to the 8089.
|
| It's interesting that Intel decided to use two different
| methods for executing coprocessor instructions. Why not just
| have the 8087 work like the 8089 does and send "jobs" to
| execute? Embedding the instruction set inside the 8086's meant
| having to put in work to duplicate the prefetch queue.
| tengwar2 wrote:
| I heard that there either was also a string co-processor, or
| that it was planned. Unfortunately I can't find anything about
| it.
| flamedoge wrote:
| how much would be 'shared'?
| convolvatron wrote:
| this used to be a thing, building up processors out of lanes:
| https://en.wikipedia.org/wiki/Bit_slicing
| MarkusWandel wrote:
| I've worked on high availability systems where CPUs were
| duplicated for reliability. In one product - which I won't name
| here - the surrounding ASICs were constructed of "self-checking
| logic" - where every data path had parity and all logic elements
| were designed such that no single wire failure could go
| undetected. The idea was that with near 100% reliability, a
| compute module could flag itself defective before recent work by
| it could be "committed" into the main memory which was
| transaction based (every segment of which also had to have at
| least two redundant copies in different modules).
|
| But who will sell you a self-checking CPU? So use two of them and
| compare everything they do from reset. This may not be so easy
| with modern CPUs with huge internal clock rates - who says that
| they will emerge from asynchronous reset in step, for example?
| But with 1990s technology it was fine.
| shrubble wrote:
| The phone switch GTD-5 had 2 separate sets of 2 CPUs for each
| function and instructions were run through both, then compared:
| https://en.wikipedia.org/wiki/GTD-5_EAX
|
| "If the results were not identical, the processors were
| immediately reset, and the pair of processors on the other card
| were brought online as the active processor complex. The active
| processor always kept memory up-to-date so that when these forced
| switches occurred, little data loss was suffered. When the switch
| was requested as a part of routine maintenance, the switch could
| be accomplished with no data loss at all."
___________________________________________________________________
(page generated 2023-12-14 23:01 UTC)