38

A lot has been said on the internet about the 6502, at 1MHz, being roughly equivalent in performance to the Z80, at 4 MHz. It is said the Z80 has a typical 4 clock ticks per instruction, while the 6502 has typically 1 clock tick per instruction and a rudimentary pipeline. It is said the Z80 ALU internally, is 4 bits when the 6502 ALU is 8 bits. It is said the z80 accesses memory every 4 clock ticks, while the 6502 accesses memory every 2 clock ticks. My question: Is it true the 6502 at 1 MHz is equivalent in performance to the Z80 at 4 MHz? Is there any practical evidence for this claim? Please only consider the Microprocessor performance, not the system built around it.

5
  • 5
    There is not a single 6502 instruction that operates in 1 tick. I think you mean to compare a 2Mhz 6502 and a 4Mhz Z80.
    – Tommy
    Feb 13, 2018 at 21:42
  • 4
    Check the Ultimate Benchmark pages for real life data.
    – Raffzahn
    Feb 13, 2018 at 21:43
  • 6
    "Practical evidence" and "don't consider the system built around the CPU" seems a bit contradicting...
    – tofro
    Feb 14, 2018 at 10:36
  • 1
    This question has got excellent answer comparing directly 6502 and Z80. The former question is broader and no its answer contains such thorough comparison of 6502 vs Z80.
    – lvd
    Feb 14, 2018 at 14:09
  • 4
    @tofro Perhaps asker wants to compare systems where the only difference is the ISA, such as a CreatiVision (6502 + TMS9918) vs. a ColecoVision (Z80 + TMS9918), or where the video/audio architecture is otherwise very similar, such as NES vs. Game Boy. Nov 3, 2018 at 15:05

7 Answers 7

43

Both processors are cacheless. So the process is fetch instruction, decode instruction, execute instruction, forget what you saw. That provides a first line of comparison.

The Z80's fastest memory fetch — the first half of an operation fetch — takes two cycles. That's always paired with another two cycles for refresh though, so the shortest instructions are four cycles long. Reads and writes that occur because the opcode tells them to generally take three cycles, though they're not always issued instantaneously.

E.g. compare PUSH or POP: the former writes two bytes to the stack, the latter reads two bytes from the stack. But because the Z80 stack predecrements, PUSH takes 11 cycles (two to read the instruction, two for refresh, one further because it hasn't yet worked out what the new stack pointer should be, then three to write the first byte and produce the next stack pointer, and three to write the second) whereas POP takes only 10 (four to get to the action, then three to read from the already known stack pointer and calculate the next followed by three to read from the next and calculate the final).

The 6502's memory cycles always last half a cycle. It does only one per cycle, leaving the bus unattended for the other half. But it always fetches at least two bytes per operation: it reads an operand regardless of whether the instruction needs one. If the instruction didn't need one, that read was wasted — it doesn't repurpose the operand it didn't need as the next operation and somehow save an access cycle.

Therefore the shortest instruction is two cycles long. Exactly half the shortest instruction of a Z80.

The 6502 also isn't always actually ready for the next memory access cycle after receiving the prior. In that case it'll do a read or write that it believes to be redundant. So it has less granularity in buying itself pauses in bus access. An example is anything read-modify-write. The 6502 will read, then perform a redundant read or write cycle of the original value while calculating what the result should be, then write.

Which ends up being 'faster' then depends on the specifics of the instruction stream but if they were fetching the same number of follow-up bytes then you'd expect the Z80 to be worse than twice as slow because its follow up accesses take three times as long as the 6502's.

In practice skilled Z80 programmers expend a lot of effort trying avoiding memory accesses by using its much deeper register set; the 6502 almost practically has a three-or-more cycle minimum because a lot of the time is spent shuffling things back and forth between the zero page.

So the 6502 tends to end up being a bit less efficient than a Z80 that is clocked twice as fast.

15
  • 2
    ...it fetches the low half of the operand, adds X to it while fetching the upper half, and then outputs an address formed from the result of the add and the newly-fetched byte while it adds 1 to the newly-fetched byte. If needed, it will then form an address using the previous low byte and the newly-computed high byte. Quite a clever design, actually.
    – supercat
    Feb 14, 2018 at 16:08
  • 3
    Code written to exploit 6502's strengths, especially its (zp),y addressing mode, is generally faster than decently-written code on a Z80 running at twice the clock rate. One perhaps-extreme but practical example was my BTP2 music player, which uses 184 cycles out of every 304 to perform four-voice wave-table synthesis. In those 184 cycles, it uses the (zp),y addressing mode 20 times, using a different address every time. Doing the same on the Z80 would have taken about 468 cycles versus 184. On a more typical note...
    – supercat
    Feb 14, 2018 at 16:16
  • 3
    @supercat the equivalent on the Z80 would be to use (HL) addressing and just adjust L — that is, assuming you'd already optimised your tables not to cross page boundaries. But the argument cuts both ways. Code written to exploit the Z80's strengths is generally faster than the same code on the 6502. E.g. the 16-bit stack pointer is often used for display manipulation: even at 4bpp that's four pixels written in 11 cycles, with target address updated. Can the 6502 do that in 5.5? I think the "code written to exploit..." argument ends up a wash.
    – Tommy
    Feb 14, 2018 at 17:41
  • 3
    @supercat: the proper 6502 equivalent, limited to a 256-bute run would be STA abs, x; DEX*2. Which I make at least 20 cycles. Not 5. About four times as slow. You're writing two bytes and updating the pointer. But this discussion can recur indefinitely. There's an endless supply of things one processor can do much more easily than the other. Neither ends up at a complete advantage.
    – Tommy
    Feb 14, 2018 at 18:35
  • 4
    Closing comment, I hope but as I've been left defending the Z80, making my comments very one sided: see atariage.com/forums/topic/201238-stardreamer ("The engine is very fast, using Lynx hardware math and was written by [me].") and github.com/TomHarte/Sam-Coupe-3d . The former is an instance when I wrote a version of the Elite 3d engine for a 6502-based machine. The latter is when I did exactly the same for a Z80-based machine. The multimachine emulator I write for fun currently stands at 4 6502 machines, 3 Z80. I can argue either side in a "what about task X?" conversation.
    – Tommy
    Feb 14, 2018 at 18:52
13

These UCSD Pascal benchmarks of an Eratosthenes Sieve Prime Number Program show that the 6502 is roughly 2x as efficient per clock cycle as the Z-80, 8086, and 8088.

For posterity, here's a partial list of the results:

System          Time (sec)  MCycles  Notes
------          ----------  -------  -----

Sage II         57          456      (68000 at 8 MHz)

NEC APC         144         705.6    8086 at 4.9 Mhz  extended memory

JONOS           162         648      (pretty good for a 4 MHz Z-80A)
NorthStar       183         732      (Z-80 at 4 MHz)
OSI C8P-DF      197         394      (6502 at 2 MHz)
H-89            200         800      (4 MHz Z-80A)
IBM PC          203         938.31   (4.77 MHz 8088)

Apple ][        390         390      (1 MHz 6502)
H-89            455         910      (2 MHz Z-80)
5
  • 12
    I don't believe in any high level languages based benchmarks. Especially when comparing old compilers/pcode executors/etc. Because then also compiler and (if any) intermediate code executor comes into the equation, changing the end result in an inpredictable way.
    – lvd
    Feb 14, 2018 at 14:11
  • 2
    @lvd That's true, but if the high level language provides exactly the function you need (like GetNextPrime()), then it's easily optimized on both platforms and then performance is dependent on the hardware again as much as in a low level language. (Not that it applies here...) Feb 14, 2018 at 16:24
  • 11
    @lvd - note that UCSD Pascal is bytecode-interpreted, so you can really say that the comparison here is to the performance of the handcrafted bytecode interpreter, not the compiler, as the compiled code is identical for all tested CPUs.
    – Jules
    Feb 14, 2018 at 18:46
  • 4
    Also, the byte code interpreters were more effectively translations of an earlier interpreter, rather than a clean room rewrite to spec. The various P-System interpreters are quite similar in architecture. In the above chart, outside of any system specific stuff (i.e. graphics), those are all running essentially identical interpreters, especially for each processor (all the Z80 are the same, all the 6502 are the same). The implementations were not particularly sophisticated by any stretch of the imagination. Feb 16, 2018 at 0:56
  • How on earth do you actually run that? Jun 26, 2021 at 15:07
13

Generally speaking, Z80 is two to three times slower than 6502 since its fastest instruction is 4 cycles and 6502's is just 2. Then, if you take into account additional instruction bytes and memory addressing, Z80 looks like it's completely behind.

But things in real life differs a bit. Z80 has more registers (7 primary, 7 secondary and 4 additional that are accessible via IX and IY halves) and a rather fast stack operations. Writing a complicated software like an operating system is much simplier on Z80 since you may use all registers anytime. And you need to share the zero page among all pieces of code on 6502. This reduces 6502's final performance.

The fastest data copying is 10.5 cycles per byte on Z80 with no address limits using the stack pointer:

ld HL, 16-bit-dataN
push HL
ld HL, 16-bit-dataN-1
push HL
...

It's rather inconvenient since the source data is interleaved with the 0x21 (ld HL) opcode but it was used in many ZX-Spectrum demos where the maximum performance was needed. On the other hand if you need a lot of inderect memory access within the relatively straightforward code (like software wave synthesizer), 6502 probably would be up to three times faster.

So, finally, I'd say Z80 is about two times slower than 6502 if they are running on the same frequency. Or 4 MHz Z80 has about the same speed as 2 MHz 6502.

But Z80 has other important advantages over 6502:

  • Built-in 7-bit DRAM regeneration. This allows using the standard CMOS DRAM like 4164 (up to 64 KBytes in total) with no additional regeneration circuitry and thus you won't have any additional delays needed for it in 6502.
  • Any physical memory (or I/O port) access in Z80 lasts two clock cycles. This means that the RAM speed may be twice lower than the CPU speed with no additional delays.
  • Z80 accesses the bus only when it needs to. So there are cycles when the CPU does not accesses the bus at all and they can be used for other hardware without any additional performance penalty.

UPD. Thanks to @Raffzahn I checked 6502 bus cycles more precisely and found out that if it runs at 2 MHz it leaves 290 ns only for the memory to be read. I.e. it requires a 3.45 MHz memory. And it leaves only a half of the cycle (i.e. 250 ns) for the memory to be written to. This means that it really requires two times faster memory than its own clock.

Z80 on the other hand waits 1.5 clocks when it reads instruction and 2 clocks when it reads or writes data. This allows 4 MHz Z80 to use 2.67 MHz memory for instruction fetching and 2 MHz memory for other operations. Since most memories perform write operation slowly than the read one, we can say that if we have a specific RAM we can use it with Z80 that runs four times faster than 6502. And since it was the RAM speed that was the bottleneck of computer building at times of Z80 and 6502, a computer with Z80 was faster. Also Z80 system benefited from hardware and software simplicity.

11
  • 2
    It's more like 4 times for the same performance - after all, it's all mostly related to RAM speed. A 1 MHz 6502 needs 2 MHz memory - the same a 4 MHz Z80 takes. Everything here revolves around the memory used.
    – Raffzahn
    Sep 17, 2019 at 23:03
  • Great answer, thanks! Can you elaborate on why the z80 have “rather fast stack operations”?
    – Biff Iam
    Sep 18, 2019 at 3:21
  • 1
    @Raffzahn Yes, bus cycle time is what we should be comparing. CPU clock frequency is just an implementation detail. The 6502 generates 2 non-overlapping phases from the clock input so a 1MHz 6502 is really 2MHz internally. If they had put a crystal oscillator on the chip then it might have been 4MHz (but still the same bus cycle time). Sep 18, 2019 at 4:06
  • 3
    @BiffIam, because memory operations with stack on Z80 is faster than any other memory ops. E.g. the quite inconvenient way of copying data via LD and PUSH I showed before takes only 10.5 cycles per byte. If you use a series of LDI (which was designed by Zylog exactly to copy data) you'll get 16 cycles per byte, i.e. 1.5 times slower. And if you use LDIR which does not require unrolling, you'll get 21 cycles per byte, which is 2 times slower than via copying via stack.
    – Kde
    Sep 18, 2019 at 20:15
  • 1
    @Kde yes, it does require memory better than 500 ns (2 MHz) to run a 1 MHz 6502. Addresses are valid at the rising edge of Phi2, while the data to be written is valid at the falling edge - or sampled at that point when reading. Do in reality it needs 470 ns or better for a 1 MHz 6502.
    – Raffzahn
    Sep 18, 2019 at 20:28
10

Many operations on the 6502 take fewer cycles than corresponding operations on the Z80; the ratio tends to be somewhere between 2:1 and 4:1. The 6502 particularly excels at accessing data structures which are 256 bytes or less; operations which cross page boundaries will often be slightly less efficient than those which don't, but code which will work across page boundaries will generally only incur a penalty if operations actually span page boundaries, while Z80 code that works across page boundaries will incur a major penalty in all cases.

Given a byte "index" stored at an arbitrary memory address, if one wants to access the index'th byte of "table", the 6502 code would be:

ldx index
lda table,x

Nine cycles if the indexing operation crosses a page boundary; eight if it doesn't. Subtract 1 if "index" is stored in the first 256 bytes of RAM. On the Z80, if the table is page-aligned, and if the address of "index" happens to be in HL--rather favorable assumptions--one may be able to get by with something like:

ld  d,tableH
ld  e,(HL)
ld  a,(DE)

in 21 cycles. If neither condition applies, but there's no need to keep the value in A and the table is guaranteed not to cross a page boundary, code would be something like:

ld  a,(index)
add a,tableL
mov e,a
ld  d,tableH
ld  a,(DE)

the total would be 41 cycles. If the Z80 code had to accommodate page crossings, it may as well use a 16-bit index, and then the code would be:

ld  hl,(index)  -- Use a 16-bit index
ld  de,table
add hl,de
ld  a,(hl)

which would be 16+10+11+7=44 cycles.

The 6502 is not terribly efficient at working with objects larger than 256 bytes, but many applications use primarily smaller objects.

18
  • 2
    @Tommy: There aren't very many operations where the Z80 doesn't take at least twice as many clock cycles as the 6502, but since Z80 machines are usually run at clock speeds which are more than double the 6502, the overall performance of a typical Z80-based computer may be slightly better than that of a typical 6502-based computer. I would expect a C compiler for the Z80 would have a bit of an edge over one for the 6502, but that's because C doesn't have ways of expressing the constructs that help 6502 programs be efficient. For example...
    – supercat
    Feb 15, 2018 at 15:28
  • 2
    ...the most efficient way to store an array of thirty 16-bit values on the 6502 is to use thirty consecutive bytes to store the lower half of each value and another thirty consecutive bytes to store the upper half. I don't have as much experience with the Z80 as the 6502, but I think I have a pretty good sense how to do things efficiently on it. The fact that every memory fetch takes 3-4 times as long on the Z80 as on the 6502 means that a Z80 program would have to avoid a lot of memory fetches not to need twice as many cycles.
    – supercat
    Feb 15, 2018 at 15:39
  • 3
    No-one writes code like this on Z80, your example is just not particularly illuminating. You don't have enough registers on 6502, so you often have to read index from memory; index will almost always be in a register on Z80, which will save about one third of the total time in your examples. I can produce similarly irrelevant examples of inefficiency of 6502 compared to Z80. E.g. standard table-less multiplication by a constant (8bits*8bits->16 bits) could be done much more compactly on Z80. So what?
    – introspec
    Feb 15, 2018 at 15:53
  • 2
    @introspec: The Z80 doesn't have a huge number of registers, and EXX is limited to swapping all three register pairs simultaneously. IX and IY can help, especially if you manipulate the two halves individually, but there's a 4-7 cycle penalty for any instruction that uses them. For the inner step of an unrolled 8x8 multiply, I figure 10 cycles worst-case on the 6502 (rol zp / bnc xx / adc mult_minus_one) and 20 on the Z80 (rlc d / jr nc,xx / add a,e) which is right in line with the 2:1 figure. Loop overhead on the z80 would add 13 cycles on the z80 or 5 on the 6502.
    – supercat
    Feb 15, 2018 at 16:17
  • 2
    @supercat I still disagree with the conclusion, but I think we've covered that. I just think your answer should actually state something like "there are few examples where the Z80 is faster" if that's your argument. I'll add on the register question as per Introspec: for the same completely flat framebuffer, with dynamic modification used on the 6502 to try to do as well as possible, my little quick attempt produces 34.5 cycles average for a Z80 Bresenham versus 30.5 for the 6502, an atypical disparity because it's a real-world example of something that fits into the Z80's registers.
    – Tommy
    Feb 15, 2018 at 16:26
5

In the 1st half of the 1980's when both processors were past their initial flaws, the generally accepted wisdom was that general purpose PCs based on a 6502 (e.g. an Apple IIe, Commodore C64, et. al.) were faster or otherwise more capable than ones based on a Z-80 (e.g. Radio Shack TRS-80).

The conventional wisdom reversed for embedded systems. For the typically hardware oriented embedded system a Z-80 based design was almost always more cost effective at any specified performance level than a 6502 based design, mainly because the processor architecture is simpler to interface with but the Z-80's ratio of processor speed to I/O bus speed is higher.

In the early 2020's neither architecture is a competitive general purpose processor for use in a PC, handheld, or similar application. Hardware decoded architectures like the 6502 and Z-80 enjoyed a brief revival in the 1990's CISC vs RISC era. The time cost of memory access doesn't scale with semiconductor feature size so the micro-coded processor architecture that allows a complex instruction set performs better when memory cycle time is longer an instruction cycle.

In embedded applications the same dynamics have left the 6502 architecture derivatives and 16 bit extensions uncompetitive with Z-80 derivatives and its 16 and 24 bit extensions. The 6502 architecture is well past its sunset. Z-80 extensions continue to be released and designed into embedded systems.

2
  • 1
    What would be an example (or two) of recent Z-80 extensions?
    – davidbak
    Nov 12, 2021 at 18:00
  • 1. What are the sources for your "generally accepted wisdom"? 2. What do you mean by "I/O bus?" Did you mean the CPU address and data buses? 3. What do you mean by "processor speed"? As mentioned in many other answers, the Z80 had a higher clock speed, but that alone was meaningless as it also took more clock cycles to do things than the 6502 did. 4. You neglect that there are important aspects of embedded systems where the 6502 clearly outperforms the Z80, such as interrupt handling latency.
    – cjs
    Nov 13, 2021 at 1:56
0

There is an issue that many just don't see. The 6502 has a very limited instruction set compared to the Z80. To write the same program, this could mean the Z80 needs much less memory and again that also affects speed. Having more instructions, has a steeper learning curve, but a trained programmer can accomplish more on a Z80.

2
0

I think a question I was just about to submit will be found duplicate of yours. But I have data to report, so I put it into the answer here.

I am looking at the memory access logic diagrams and it strikes me that the Z80 runs through 3 clock cycles for a memory read or write. There is even talk about throwing the /WAIT line to stop the CPU when memory access takes longer. In addition it has a very annoying built-in refresh cycle. This to me says that this CPU uses 4 cycles where the 6502 uses only one. After all, the 6502 makes regular memory access in almost every clock cycle (in every clock cycle actually, only that sometimes the result is not used.)

enter image description here

Here is 6502:

enter image description here

Seems to me that in order for the Z80 to catch up with the 6502 the former needs to be clocked at 3-4 times the latter. So if 6502 would run at 1 MHz (but I think 4 is possible) then the Z80 would need to be clocked at 4-16 MHz to make up for it.

It is clear. And therefore, an easy benchmark should be just bulk writing and reading operations, which can be done very comparably. The Z80 in addition of being slower to begin with also has multi-byte opcodes. It also requires instructions to push data through the 4-bit (!) ALU just to find out if a register load was zero, whereas 6502 sets the Z flag about every time you handle a register.

The limited instruction set of the 6502 might be considered "RISC" compared to Z80 being very CISC-y. The bulk copy operation supposedly is fast, but in actuality I have seen, it makes additional extra memory accesses to interpolate the M1 cycles and the annoying DRAM refresh in sync. So, it's tough for the Z80 to beat the 6502 in simple tasks.

In complex tasks the only thing I see in the Z80 that might make it win in the end is more registers, the register swap rather than a lot of push and pull. Built in IO is cool for simple operations, but fast operations would be DMA anyway. And even for DMA it seems that the DRAM RFSH issue becomes a problem.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .