Hey guys,
Thank you for your inputs!
I have to apologize first, I was not clear enough to begin with. The CPU I created was “inspired” by the Z80, Motorola 68000 and some other architectures of that era, but it’s completely different. It’s totally “fantasy”.
The inspiration from the Z80 limits to how some mnemonics are written (LD - for load, SR, SL - for shift right, left, DJNZ, etc…), how the registers can have compositional forms:
i.e.
A, B, C, ... Z but also:
AB, BC, CD, ..., ZA (colliding 16 bit)
AB, CD, EF, ... (non-colliding 16 bit)
...
ABCD, BCDE, and so on.
And finally, how the registers work with instructions. Basically all instructions can use all registers in any form, so there’s no specific “accumulator” or “memory incremental” or anything like that.
@drogon
So, I can’t reference anything against the Z80 since it’s a totally different CPU. I am implementing a higher level programming language compiler which I called MOSAIC which is a cross between BASIC, some simple C# and the ability to have images as variables you can work with similarly as with int(s), for example. But I feel the benchmarking should be done at assembly level, moreover, even at machine level so I can get as accurate as possible (per host machine).
One other thing that would taint the results would be the fact that most of the older hardware (as far as I am aware of) implemented BASIC as an intepreter, not as a compiler (which I am doing). So, right from the start, whatever you write with MOSAIC would be way faster than the interpreter equivalent.
However, I do think it’s an interesting idea to “port” some sort of old benchmarking programs and see how they run in comparison (with the notes above made very transparent). I think it’s a great idea! Thanks!
@oldben
I am rather ashamed to admit that in 2 and a half years since I wrote the RAM controller, I never considered the nature of it until you asked these questions.
My RAM is completely inside the CPU, next to the registers. Fetching data from memory or registers is the same thing in terms of speed, or very close, depending on how many bits you fetch (8, 16, 24 or 32).
I don’t have a data bus, nor anything required to sync with the RAM. It simply fetches from the CPU RAM in a single cycle. And I think that answers my initial question, since real hardware (for cost and engineering reasons) does not tipically do this.
@EdS
Indeed, I thought about the bias that testing one single instruction can introduce, but, I also think it should not matter much. Say we write a very basic emulator with 6 instructions:
LD r, immediate
ADD r, r
LD r, (r)
LD (r), r
JZ r, immediate (if r == 0, PC = immediate)
HLT
Probably the “fastest” instruction would be HLT, which should take 3 cycles:
- increment PC
- read next instruction from memory
- halt
Now, let’s benchmark at CPU level and run 1000 HLT instructions which takes a second. This means (I think) a theoretical 3Khz CPU so far.
But how about the other instructions. Let’s say we benchmark the ADD r, r and we find out it takes 2.3 seconds. Longer, but that’s fine. It simply means internally, using the same logic, it uses 6.9 cycles to reach the end of that addition. The CPU frequency should be the same, only the number of cycles is increased because it does more internally.
Below is a sort of benchmark I made on all instructions except “WAIT” and “INT”.
I excluded WAIT for obvious reasons, it simply waits and taints the result, and INT because it’s actually a system function call. For example, I draw rectangles with such an INT and depending on rectangle size it takes more or less.
I also noticed my NOP instruction there takes more time than other more complex instructions. I fail to understand why since there’s no way the runtime execution can be optimized since it’s tightly binded to the RAM, so there’s no way for the CPU to know what’s the next instruction until it actually reads it.
Maybe the execution as a function is somewhat cached somewhere with some lookups, but that would be the execution interpreter, not anything I did. I still need to figure that out.