«More CISC-y» does not by itself mean «harder to optimise for». For compilers, what matters far more is how regular the ISA is: how uniform the register file is, how consistent the condition codes are, how predictable the addressing modes are, and how many nasty special cases the backend has to tiptoe around.
The m68k family was certainly CISC, but it was also notably regular and fairly orthogonal (the legacy of the PDP-11 ISA, which was a major influence on m68k). Motorola’s own programming model gives one 16 programmer-visible 32-bit registers, with data and address registers used systematically, and consistent condition-code behaviour across instructions.
Contrast that with old x86, which was full of irregularities and quirks that compilers hate: segmented addressing, fewer truly general registers (5 general purpose registers), multiple implicit operands, and addressing rules tied to specific registers and modes. Even modern GCC documentation still has to mention x86 cases where a specific register role reduces register-allocation freedom, which is exactly the sort of target quirk that makes optimisation more awkward.
So…
68k: complex, but tidy
x86: complex, and grubby
What worked for x86, though, was the sheer size of the x86 market, which resulted in better compiler support, more tuning effort, and vastly more commercial optimisation work than m68k. But that is not the same claim as «68k was harder to optimise because it was more CISC-y».
Notice I didn't write harder to optimize for - I am not talking about optimizing code, but optimizing the actual internal microarchitecture.
Turns out m68k orthogonality results in explosion of complexity of the physical implementation and is way harder to optimize, especially since compilers did use that. Whereas way more limited x86 was harder to write code generation for, but it meant there was simpler execution in silicon and less need to pander to slow path only instructions. And then on top of that you got the part where Intel's scale meant they could have two-three teams working on separate x86 cpu at the same time.
Once again – respectfully – this remains largely twaddle as the facts themselves state otherwise.
Even at the microarchitecture level, the hard part is not raw CISC-ness but irregularity and compatibility baggage. In that respect x86 was usually the uglier customer.
High-end x86 implementations ultimately scaled further because Motorola had less market pressure and fewer resources than Intel to keep throwing silicon at the problem, not because m68k was somehow harder to optimise.
Later high-performance m68k cores did what later x86 cores also did: translate the architected variable-length instruction stream into a more regular internal form. Motorola’s own MC68060 manual says the variable-length M68000 instruction stream is internally decoded into a fixed-length representation and then dispatched to dual pipelined RISC execution engines. That is not evidence of an ISA that was uniquely resistant to microarchitectural optimisation. It is evidence that Motorola used the same broad trick that became standard elsewhere: hide ISA ugliness behind a cleaner internal machine.
There is also a deeper point. The m68k ISA was rich, but it was comparatively regular and systematic at the architectural level. The m68k manuals show a clean register model and – notably – consistent condition-code behaviour across instruction forms. That kind of regularity is exactly what tends to help both compiler backends and hardware decode/control design. By contrast, x86’s biggest hardware pain historically came not from being «less CISC» than m68k, but from being more irregular and more burdened by backward compatibility.
Lastly, but not least importantly, CPU's were not the core business of Motorola – it was a large communications-and-semiconductors company, with the CPU's being just one product family within a much larger semiconductor business.
There was no clear understanding within the company of the rising importance of CPU's (and computing in general), hence the chronic underinvestment in the CPU product line – m68k did not see the light of highly advanced, performant designs purely because of that.
Well, here I am following what people who worked on CPUs at the time wrote.
And from the point of microcoded system like x86 and 680xx were (including 68060) it is important to how many microinstructions your instruction stream will decode - something that greatly favours ISAs that are not orthogonal - and major reason why x86 often has 1.2-1.6 ratio of microinstruction to instruction for overall program code.
Orthogonality makes it problematic because while it's easy in "interpreter microprogram" style of old and easy to program in assembly for, it means that for example for 68k you have to deal with many addressing modes for every operand - whereas x86 pretty much fuses it between 1 to 2 instructions because only one operand can have any computed address, and scope of available computation is limited (even compared to just 68000).
This means that while both architectures can use "translation microcode" approach, one (x86) will easily decode into one or two 72bit instructions (using P6 here) with worst case involving somewhat rare 3 operand form of memory address (which still can only happen for one operand of the instruction, not both)
> Since when were payment networks latency sensitive?
Since the advent of e-commerce, POS-networking and fraud detection systems in 1990's-2000's.
User-facing and authorisation path are highly latency sensitive. It includes tap-to-pay, online checkout, issuer authorisation, fraud decisioning, and instant payment confirmation – even moreso for EFT payments.
> […] 2-5 seconds more from card presentation to getting approval back.
This is the mid-1990's level QoS when smaller merchants connected the acquirer bank via a modem connection, and larger ones via ISDN.
Today, payments are nearly instant in most cases, with longer than one-second card payment flows falling into the exceptions territory or inadequate condition of the payment infrastructure.
Years ago I made harissa out of peppers for sauce for baked chicken wings. To my surprise it tasted tomato-ey.
After doing some Google searches I realized the plants were related and eventually it sort of made sense. Peppers are almost like a very dry, very firm tomato.
In hindsight it's obvious but at the time it was very surprising.
but for some reason my fealty to potato does not extend to tomatoes and eggplant quite the same way. i feel toward potatoes sort of how gary Larson feels about cows
PDP-11 was a major source of inspiration for m68k architecture designers. The influence can be seen in multiple places, starting from the orthogonal ISA design down to instruction mnemonics.
It is quite likely that not allowing the misaligned access was also influenced by PDP-11.
If I'm not mistaken, microcode is a thing at least on Intel CPU's, and that is how they patched Spectre, Meltdown and other vulnerabilities – Intel released a microcode update that BIOS applies at the cold start and hot patches the CPU.
Maybe other CPU's have it as well, though I do not have enough information on that.
> In Linux the default swap behaviour is to also swap out the memory mapped to the executable file, not just memory allocated by the process […] I believe both Windows and macOS don't swap out code pages, so the applications remain responsive, at the of (potentially) lower swap efficiency
Linux does not page out code pages into the swap. You might be conflating page reclamation with swapping instead.
In Linux, executable «.text» pages are mapped[0] as file-backed pages, not anonymous memory, so when the kernel needs to reclaim RAM it normally drops those pages and reloads them from the executable file on the next page fault once they are accessed again (i.e. on demand) rather than writing them to swap.
In this particular regard, Linux is no different from any other modern UNIX[1] kernel (*BSD, Solaris, AIX and may others).
Yes, you are correct, I wasn't precise enough. It doesn't make sense to swap the existing code pages, they are just unmapped. (And that's the reason why you get "text file busy" when doing scp over the file: since the OS relies on the fact that the .text pages can be safely unmapped it needs to guarantee that they stay read-only)
> In 1970 it might have been the only way to provide a flexible API, but nowadays we have a great variety of extensible serialization formats better than "struct".
Actually, fork(2) was very inefficient in the 1970's and for another decade, but that changed with BSD 4.3 which shipped an entirely new VMM in 1990 in 4.3-Reno BSD, which – subsequently – allowed a CoW fork(2) to come into existence in 4.4 BSD in 1993.
Two changes sped fork (2) up dramatically, but before then it entailed copying not just process' structs but also the entire memory space upon a fork.
AFAIR it was quite efficient (basically free) on pre-VM PDP-11 where the kernel swapped the whole address space on a context switch. It only involved swapping to a new disk area.
I used MINIX on 8086 which was similar and it definitely was not efficient. It had to make a copy of the whole address space on fork. It was the introduction of paging and copy-on-write that made fork efficient.
Oh, is that how MINIX did that? AIUI, the original UNIX could only hold one process in memory at a time, so its fork() would dump the process's current working space to disk, then rename it with a new PID, and return to the user space — essentially, the parent process literally turned into the child process. That's also where the misconception "after fork(), the child gets to run before the parent" comes from.
It is not helpful because comparing English from 1000 AD with Modern High German is the wrong premise to start off with.
The correct and more interesting comparison would be with Old High German from around the same time although it did not indicate the umlaut in the spelling at the time (which would happen 400-500 years later) – even though the i-umlaut had already developed.
So «schön» was «scōni» (or «sconi») in OHG. Also, ö and ü developed from /o/ and /u/, so juxtaposing them with English ē is likely incorrect.
It is not helpful because comparing English from 1000 AD with Modern High German is the wrong premise to start off with.
I hear this premise repeated time and time again. Search the internet. I believed this premise, and actually started studying German again while waiting for my Old English textbook to arrive. It did not help.
I do not need to search the internet as I am fluent at German as well.
The knowledge of Modern High German helps little to none as far as the comprehension of Old English is concerned. From a modern German speaker's perspective, Old English – with a relatively small number of exceptions – is gibberish.
Before the wide adoption of Unicode in mainstream operating systems, quite a few people used -- (two ASCII minus signs) to differentiate between a hyphen and a dash (of either pedigree), and some people used -- in emails and online where a dash was required.
Most think that it came from TeX, which had -- (for an en dash) and --- (for an em dash, although I don't think I have ever observed it out in the wild outside TeX), but in fact, the habit well predates TeX and goes all the way back to typewriters where typists habitually hit two hyphens in a row to approximate an em dash. The approximated em dash was described in hard-copy manuscript preparation rules such as The Chicago Manual of Style.
So, if you have ever used a typewriter or TeX, you can claim an even richer than 20 years’ heritage of using the em dash.
«More CISC-y» does not by itself mean «harder to optimise for». For compilers, what matters far more is how regular the ISA is: how uniform the register file is, how consistent the condition codes are, how predictable the addressing modes are, and how many nasty special cases the backend has to tiptoe around.
The m68k family was certainly CISC, but it was also notably regular and fairly orthogonal (the legacy of the PDP-11 ISA, which was a major influence on m68k). Motorola’s own programming model gives one 16 programmer-visible 32-bit registers, with data and address registers used systematically, and consistent condition-code behaviour across instructions.
Contrast that with old x86, which was full of irregularities and quirks that compilers hate: segmented addressing, fewer truly general registers (5 general purpose registers), multiple implicit operands, and addressing rules tied to specific registers and modes. Even modern GCC documentation still has to mention x86 cases where a specific register role reduces register-allocation freedom, which is exactly the sort of target quirk that makes optimisation more awkward.
So…
What worked for x86, though, was the sheer size of the x86 market, which resulted in better compiler support, more tuning effort, and vastly more commercial optimisation work than m68k. But that is not the same claim as «68k was harder to optimise because it was more CISC-y».reply