4 ms·
Easily one of my favorite archs, at least as far as the idea of it goes. IMO the most pure classic 5 stage RISC. Divide is split into each cycle's ops, iterat
by monocasa 5y ago
Easily one of my favorite archs, at least as far as the idea of it goes. IMO the most pure classic 5 stage RISC. Divide is split into each cycle's ops, iterate for as long as your results need. It's pretty easy to get to a point where you can just read the hex of the opcodes as three address RISC with 16 bit instructions and 16 registers means the first nybble is the opcode, and the other three nybbles are the registers. And the whole thing feels like someone told some engineers that they have to make a RISC with half the gates of an equivalent MIPS and the mad lads actually did it, and did it well.
A little ascetic for these days though, IMO.
- AlotOfReading 5y agoI had a completely irrational dislike for the division. You could use a loop, but then you were wasting >3/4ths of your cycles on shifting and branching. If you had the misfortune to have the compiler generate division code, it'd usually fill the branch delay slot with a NOP as well. The solution was simply to stick 8/16/32 division instructions in a row, but that felt inelegant. I spent a day writing some silly routine that averaged ~22 cycles over 32 bit integers just because it annoyed me so much.
- freemint 5y agoDo you still have access to this?
- AlotOfReading 5y agoSadly not. I was pretty terrible about version control and saving things from that early in my career. The concept was pretty simple though: division was 1-bit so you could simply do fewer divisions if you had smaller numbers. The first version was something like a BSR -> jump into the divide table. That probably would have been the place to stop, but I was clearly terrible at profiling because I remember adding all sorts of special case logic on top to handle things like powers of two, which likely ended up being slower in practice because cycle times aren't everything.
- girvo 5y ago> I was pretty terrible about version control and saving things from that early in my career. You and everyone else, I feel. I tried to find some of my early projects from two decades back, and despite having backups floating around on various hard-drives, I could not find them to save my life. I wish I'd accepted the good word of CVS/SVN back then!
- exikyut 5y agoThis is not an answer to your question as asked, but the direction it goes may prove interesting: https://lab.whitequark.org/notes/2020-04-06/synthesizing-optimal-8051-code/ https://lab.whitequark.org/notes/2020-04-06/synthesizing-opt... (Found this a while back, mild impostor syndrome moment much)
- freemint 5y agowhitequark is pretty genius. I think i saw that on her twitter previously but thanks for the trip down memory lane.
- rvense 5y agoBranch delay slots make. assembly weird
- ithkuil 5y agoGo away NOP!
- wyldfire 5y agollvm has a cool tool to statically evaluate your code on a model scheduler [1]. Not sure how many backends are supported beyond x86, but it looks pretty handy. [1] https://llvm.org/docs/CommandGuide/llvm-mca.html https://llvm.org/docs/CommandGuide/llvm-mca.html
- mhh__ 5y agoNon-x86 architectures are vaguely supported, however the key thing here is that it needs a scheduler model i.e. architecture isn't enough. I think the basics of in-order target support is being worked on (possibly merged, haven't been keeping up to date) https://reviews.llvm.org/D94928 https://reviews.llvm.org/D94928 Other tools to do this exist (or have existed, Intel IACA rest in peace), but I'm slightly sceptical how useful they are in practice. They can't model anything transient in the processor (can't easily, at least) like branch prediction and the memory hierarchy. That and there's only so much detail one can fit inside a model.
- dragontamer 5y ago> Divide is split into each cycle's ops, iterate for as long as your results need. You know what would be better? If you had a decompression routine built into the CPU that would convert division and modulus commands into this loop at the micro-code level. That way, a divide / modulus cycle (probably taking 20 instructions taking 50+ bytes) can be compressed into a singular instruction (1 instruction taking 4 bytes)... using less L1 cache.
- monocasa 5y agoI mean, it doesn't have any microcode, and does better than MIPS ironically at achieving the whole "Microprocessor without Interlocked Pipelined Stages" thing because of directly exposing the divide pipeline in single cycle units. Having to add pipeline interlocking from the EX stage just for that as well as the microcode itself would have been non trivial from a gate count perspective on a core that's already cutting gates left and right. And it's neat to be able to choose the divide precision you need down to the cycle. I agree though in the general case, hence why I end with it being a little ascetic these days.