6 ms·
I recently was curious about the relative performance of the classic CPUs, so I made this table to compare their memcpy performance: https://github.com/jhallen
by jhallenworld 6y ago
I recently was curious about the relative performance of the classic CPUs, so I made this table to compare their memcpy performance:
https://github.com/jhallen/joes-sandbox/tree/master/classic-cpu https://github.com/jhallen/joes-sandbox/tree/master/classic-...
- klelatti 6y agoThat's really interesting. Shows that optimising for each CPU presented a different challenge each time. I remember hearing Steve Furber say that they realised that memory bandwidth was the biggest constraint in 8/16 bit CPUs so the ARM1/2 really focused on this and it shows (in fact I think they approached Intel with the idea of commissioning an 8086 with more bandwidth but were turned away - funny how things work out).
- Someone 6y agoI think you can speed up the 6502 version by moving it into the zero page and not using indexed mode. Of course, zero page memory is even more restricted than the 64kB you have in total, but that might be worth it in some cases. Even if this isn’t in the zero page, it surprises me that those expensive x indirect loads and stores are cheaper than worth having to increase the source and destination addresses often, but that probably is because my 6502 is very rusty. Also: I stared at that code for a while, but couldn’t figure out why that jmp immer is there. If you move the 3 instructions starting at lastpage to the end, it can be removed, can’t it? (I didn’t check, but there may be further code shuffles that do not decrease the number of instructions, but do decrease the number of branches and with it, the number of cycles spent)
- jhallenworld 6y agoI knew 6502 people would improve it :-) >moving it into the zero page and not using indexed mode I'm not sure I follow.. you mean restrict the memcpy to only within the zero-page? >jmp inner.. Yeah, it doesn't matter to much, not in the inner loop. You could move the start of the code to right after the rts also..
- Someone 6y agoNo, moving the code into the zero page. See https://retrocomputing.stackexchange.com/a/92 https://retrocomputing.stackexchange.com/a/92 for what the Basic in the Commodore 64 does. Increasing an address is faster in the zero page, and self-modifying code is faster. That combines the two.
- jhallenworld 6y agoOh I see: inc $c9 5 cycles 00c8: lda $xxxx 4 cycles vs. lda $xxxx,x 4 inx 2 Mine is still faster...
- Someone 6y agoLuckily, I said my 6502 is rusty :-). You can win a cycle increasing the high byte of pointers, but that probably isn’t worth the zero page memory in most cases.
- jacquesm 6y agoThe 6809 could move its zero page around!
- Flow 6y agoAnd stack too IIRC.
- jacquesm 6y agoThat's correct. The reason for this is that they foresaw using the CPU for multi-tasking with each application using it's own code, data, stack and zero page (scratch) data. That's also why it has relocatable code. A small multi-tasking OS called OS-9 was written and released for it: https://en.wikipedia.org/wiki/OS-9 https://en.wikipedia.org/wiki/OS-9
- rwmj 6y agoOn the Z80, LDIR is not as fast as unrolling the loop to produce a block of LDI instructions. You can jump into the middle of the block at count % blocksize to copy sizes which are not a round number. This was a fairly common game trick. http://map.grauw.nl/articles/fast_loops.php#unrollingldir http://map.grauw.nl/articles/fast_loops.php#unrollingldir The reason for this is a bit obscure, but was caused by a peculiarity of the Z80's implementation of LDIR. For each iteration it actually decrements PC by 2 and reloads the instruction. This is apparently so that the CPU can still service interrupts during the loop. Since LDIR is an "extended" instruction it has to reread 2 bytes. LDI being a single byte was quicker to read. https://retrocomputing.stackexchange.com/a/4745 https://retrocomputing.stackexchange.com/a/4745
- jhallenworld 6y agoAh, you are right, LDI is only 16 cycles.. I will update the Z-80 entry. I like the jump in the middle trick to avoid the test after each instruction.
- kayamon 6y agoThe fastest way to memcpy by far on a Z80 is to point the stack register at your data and PUSH/POP the registers onto it. Many games used this (e.g. see 'Cobra', 1986)
- Flow 6y agoHow does that interact with the NMI on the ZX Spectrum? I'm not a ZX programmer, but I've read that ZX has a NMI that fires and can't be reprogrammed.
- rwmj 6y agoYou can't use it if the system has an NMI because it could push a return address on the stack at any time (unless there's a way to mask the "non-maskable", perhaps by disabling all devices that could generate NMIs). Luckily there was no NMI on the basic Spectrum. I believe it was only used by those game copying dongles where you would press a button to stop the system and snapshot memory.