31

When RAM is at a premium, as it was in the old days, a greater code density of an instruction set can be a substantial advantage.

(Click saver: Code density refers loosely to how many microprocessor instructions it takes to perform a requested action, and how much space each instruction takes up.)

How did the popular 8-bit microprocessor lines (6502, ..., and 8080, ...) compare against one another in that regard? An attempt to look up "6502 vs 8080" or "6502 vs Z80" brings up discussions about clock frequencies, clock cycles per instruction, programming preferences, etc. but not about the code density.

2
  • 1
    An option would be to use some C (for example) cross-compilers and compare the results on a significant program with options turned on for space optimization. 6502.org/tools/lang indicates a port of gcc for 6502, here z88dk.org/forum for Z80. Aug 13 '17 at 10:34
  • Code density depends very much on the skills of the coder. I found the conditional return instructions of the Z80 to be very helpful in condensing code. Jun 18 at 19:26
36

An instruction set can be considered as a Huffman coding of an idealised instruction stream. So the question is really asking which CPUs have a good balance of short encodings for common tasks to longer encodings for rare tasks. However, it is not sufficient to just look at the encoding of individual instructions because a RISC instruction generally does less than a CISC instruction, and real-world code need to be considered.

Further, it is possible to increase code density by creating a more efficient virtual machine to execute bytecode, threaded code (not to be confused with modern-day threads), or a variety of other similar techniques. All of these tricks are effectively instruction sets in their own right.

But you're not really asking about the theory, but hard data. The paper that immediately came to mind was Code Density Concerns for New Architectures (Citation, Presentation, Paper). It is more biased towards modern architectures, but it does include the Z80 and 6502 in (some of) its results.

You can intuit the likely results for similar retro CPUs: the 8080 is a subset of the Z80 so will be less dense. Likewise the 8088 is a subset of modern x86 and also less dense and arguably not really an 8 bit CPU anyway, or we could just include the 68008 or 65816.

To crudely summarise the paper's results: Modern x86 tends to be the most-dense code; CISC, ARM Thumb, Z80 and the embedded-optimised CPUs are a close second; RISC and 6502 are a respectable third (many don't think of the 6502 as being RISCy!), and Itanium and Alpha come in a poor fourth. If you ignore the Itanium outlier, there's only about a factor of 1.5 difference between all the CPUs tested.

So if you're looking for a (popular) retro CPU with the absolute-highest code density, you want the Z80.

8
  • 2
    It would be interesting to see where Z80 and 6502 derivates like the 65816 or Z180 series went with regards to code density. Both included a number of new and useful instructions besides simply widening buses and adding on-chip peripherals.
    – tofro
    Aug 13 '17 at 9:31
  • 10
    Now thats a very interesting paper. Thanks a lot. Reading it, I'd be careful in interpreting too much, as the 'hand optimized assembly' sounds more as it is. Looking at the 6502 version it seams that the coder wasn't realy using teh 6502 ISA. I know it's not easy for everyone, but when switching architectures, the way of thinking also needs to be changed. /370 works different then 6502 sounds trivial but is fundamental.We might need more research here. Still. Cool find.
    – Raffzahn
    Aug 13 '17 at 10:35
  • 3
    @tofro the 6502 and the Z80 are very different beasts. The 6502 has short instructions for operating with the $00-$FF memory page, and only three registers, and the Z80 has more registers and 16-bit operations. The Sargon programmers thought the 6502 nicest for chess. Aug 13 '17 at 15:37
  • 3
    @LưuVĩnhPhúc, Itanium theoretically packs three instructions into 128 bits, so it's inherently lower-density than anything but the CISC instruction sets. Density is then reduced further because of limitations on which instructions you can pack together (eg. a bundle can't contain more than a single FPU instruction, and you can't pack two instructions that depend on each other into the same bundle).
    – Mark
    Aug 15 '17 at 0:27
  • 4
    It would be interesting to see where the 6809 lands in all of this. Like the Z80 it has several 16-bit index registers, but also has a direct page (a relocatable version of the 6502's zero page), a plethora of addressing modes (including options for 5-, 8- and 16-bit offsets), and generally seems designed for high code density (e.g. PSH/PUL to either stack do up to eight registers in a single two-byte instruction).
    – cjs
    Oct 15 '19 at 2:51
4

I was going through the literature produced by Zilog in the 1980s and noticed that in their "Microprocessor Applications Reference Book, Volume 2" (1983), nicely scanned for us by BitSavers, they attempted to compare Z80 vs 6502 (see Section 2 "Z80 CPU vs 6502 CPU. Benchmark report"). Given that this comparison was produced by one of the direct competitors, you can of course take their findings with a large pinch of salt. However, their comparisons do not seem overly unbalanced, and my only substantial complaint is to do with the fact that they included into their battery of tests several tasks where Z80 would have a substantial edge (such as data copying and linear data searching routines, both of which can be done on Z80 using designated commands). All their programs are included with the report, so you can take a closer look at the codes and conclude for yourself, how reasonable their codes were.

In any case, their results are interesting and provide a bit more specific indication of the range of practical differences between the CPUs. Tables 4 and 5 from their report compare the code density in two ways, by comparing the number of bytes for each program and by comparing the number of lines in each program: enter image description here

I'd say that the reported factor of 2.5-3 lower code density on 6502 is mostly due to trying to compare averages, that are, as usual for averages, overly biased by the outliers (such as the example of linear string searching). However, if instead of computing average ratios, we were to compute median ratios, we will get a more reasonable estimate that Z80 code is about twice as dense as 6502 code, both in terms of the number of lines of code and in terms the number of bytes it occupies.

6
  • 1
    The 6502 code examples are contrived to be bad. Code to copy up to 256 bytes from one hard-coded address to another would be 11 bytes on the 6502. For up to 129 bytes, I'd normally use ldy #size-1 / lp: lda src,y / sta dest,y / dey / bpl lp; for 130-255, ldy #size / lda (src-1),y / sta (dest-1),y / dey / bne lp. For 256 bytes, I'd start y at zero and use an increment loop. If the source and/or destination were pre-stored in zero-page locations, the 6502 code would be 1-2 bytes smaller. Writing concise and efficient code on either processor requires laying things out carefully...
    – supercat
    Jun 18 at 20:20
  • 1
    ...but the 6502 is a bit more flexible in how things are laid out, since its indexed addressing modes automatically handle page crossings reasonably efficiently (a one cycle penalty which generally only applies if page crossings occur). The Z80's indexed addressing modes, by contrast, spend multiple cycles accommodating the possibility of a page crossing whether or not one occurs.
    – supercat
    Jun 18 at 20:22
  • Yes, I thought about these examples and did not like them too. Then again, when I am thinking about what makes x86 so good for size coding, I invariable come to the conclusion that it is all kinds of STOSB, MOVSB etc. I.e., yes, showing that LDIR can copy things compactly, or that CPIR can do linear searches easily, is in many ways pointless. On the other hand, in practice, LDIR is extemely valuable, and it does save space in the end. So, I agree that such comparison could have been done better, but I still think that as far as this type of exercise goes, they've done fairly OK.
    – introspec
    Jun 18 at 20:30
  • Z80 code to copy e.g. 57 bytes from one fixed address to another will take 11 bytes. 6502 code to do likewise will also take 11 bytes. The Z80's 11-byte copy technique will handle bigger chunks at no extra cost in code space, but that's not usually a huge advantage. Indeed, the Z80's LDIR and LDDR would have been more useful if they'd used B rather than BC as a loop counter, since loading B would be faster than loading BC, and since the instruction could easily have been made two cycles faster if it used an 8-bit counter rather than a 16-bit one.
    – supercat
    Jun 18 at 20:39
  • 1
    The 6502 is much better at dealing with data structures that are 256 bytes or less (with a slight preference for those under 128 bytes) than at dealing with larger ones. The Z80 often has a slight edge when dealing with larger data structures, but the 6502 has a major advantage when dealing with smaller ones.
    – supercat
    Jun 18 at 21:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.