Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

So, 1 instruction, but how many clock cycles does it take to load 16 registers?


Who cares? Feel that code density !

More seriously, yup: if you read the architecture manual this instruction can take a long time. It's also a pain for a OoO (not superscalar!) cpu to keep track of all the dependencies.

It made complete sense back in the early 80s when the instruction set was designed, but like universal condition code dependent instruction execution it was dropped from ARM64 for good reasons.


Superscalar doesn't really matter here (just throw in an interlock), but out of order very much does.


True! I was (inappropriately) thinking of SS as a combination of both.


Why would it be harder for OoO to keep track of this than N mov/load instructions? It is just that the dependency tracker is working in instruction space?

As mentioned before these were microcoded anyways so it may end up "compiling" down to N loads which should track just as well.


Imagine you hit a bus error on the last memory access of LDM. You already updated 15 registers, so now you need to undo all of that.

If instead you had executed 16 separate LD instructions, all of them would have retired and update state by the time the last one gets the bus error.

It’s all doable of course, but it means your OOO algorithm and physical implementation need to handle a lot more state in flight.


Why couldn't you just not undo it, and have it read/write twice? This wouldn't be a problem if you're accessing normal ram, like the prologue and epilogue of a function. Add a comment to the manual saying to not use this instruction when reading/writing hardware registers where accessing it changes state.


Not all instructions are re-startable. ldm/stm that writes back to the base register is only re-startable if the write-back and the update to PC are last.

The microcontroller-scale cores have a few extra bits in the control/status register that govern restart of an interrupted ldm/stm or IT (if-then, a form of hammock predication).


> Imagine you hit a bus error on the last memory access of LDM. You already updated 15 registers, so now you need to undo all of that.

Irrelevant. "Undo all of that" is just a matter of using an older version of the register alias table. The retirement process has do to that for any and all faults anyway.


My point was that undoing multiple writes is not as easy as undoing one write. Your register file (really, reorder buffer) either needs to add more write ports to it, or you need a state machine to complete that clean-up over multiple cycles.

Without that instruction, your hardware design could have assumed that reverting state can always be done in one cycle. That makes the hardware implementation easier.


Your point is based on a fundamental mis-understanding of what the reorder buffer (ROB) is doing.

Any time there is a fault, it is detected by the retirement stage as it inspects the ROB. There are already hundreds of state changes that must be rolled back: all of the succeeding entries in the ROB. So the work performed by the recovery mechanism isn't changed by the amount of clobbered state because it is completely clobbered! The ROB must rewind it all.

The register file doesn't need any additional ports, because the fault recovery mechanism doesn't touch the physical registers. It only updates the register alias table (RAT) to point to the appropriate registers. But that machine must be capable of restoring 100% of the register pointers very quickly no matter what. Whether the faulting instruction touched one, two, or 16 registers doesn't matter. The 100+ updates following it are enough state that the answer must be: "Everything".


You are correct for complex CPUs with actual ROB with hundreds of entries. For those micro-architecture, LDM is not particularly stressful. I was focused on the micro-controller case, with much simpler pipelines. LDM is one of the instructions causing the pipeline a lot more headaches than it's worth.


Microcontrollers don't need additional ports either. Take a look a the ARMv7-M status/control register. It has a few bits of state to allow ldm, stm, and if-then to be resumed in-place.

At that scale, those mechanisms aren't micro-coded, they are state-machined. You just have to restore the state machine.


Chances are high it depends on the CPU, whether the memory read/written straddles a cache line, etc.

https://gab.wallawalla.edu/~curt.nelson/cptr380/textbook/adv... says it takes 2 + N cycles, plus 2 if the PC is in the list.

Storing them takes 1 + N cycles, according to that PDF.

(Also, this kind of instruction isn’t a novel idea. 68k had MOVEM, for example (http://68k.hax.com/MOVEM))


According to https://developer.arm.com/documentation/ddi0165/b/instructio... , it's 17 clock cycles if the next instruction uses the last register (r15), otherwise 16


If anyone is interested why R15 is special cased here a bit, it's because R15 is the program counter and that extra cycle is the interlock where they'd otherwise have to put a delay slot.


Hmm, I didn't know about that. Then it would be 20 or something.

(The special case I accounted for is because there's a bubble in the instruction pipeline if the next instruction uses the last register)


Are instructions typically variable in the number of cycles it takes?

If, as the article claims, pop is truly aliased to ldm, then I'd expect it to be very fast.


They are, this one takes from 2 to something like 20 cycles, depending on the number of registers, an whether the PC is one of them.


> Are instructions typically variable in the number of cycles it takes?

Very much so, either due to memory latency or just inherent complexity. For example, a single division instruction can easily take the same time as ten adds.


I meant variant for the same instruction. Is expect a divide to be slower than an add but I wasn't sure if a single instruction would have a range.


Yes, even in very simple architectures instructions often take different numbers of cycles.


Less than 16 individual loads since you're skipping 15 opcode fetches




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: