Cool, I love weird architectures. This one has attributes in common with an exposed pipeline - the sort of thing where one instruction writes to a register, then the next 10 cycles can read the stale version from that register, and then the 11th will finally see that value. That's cute from a hardware perspective and deeply confusing to program against. It looks like a register in "straight" is a circular buffer which ticks on instruction execution and a register in "clockhands" is a circular buffer which ticks on writes to the register, which would indeed be a substantial improvement.
This is another variant of statically schedule lots of code ahead of time, moving work from the hardware into the compiler. Works really well if basic blocks contain many instructions and memory latency is known in advance, at least to within tight bounds, and you put enough effort into the compiler.
Traditionally basic blocks are short and memory latency is all over the place, at which point you really want to schedule things at runtime. Hence CPUs and GPUs - both do a load of nominally avoidable work at program runtime. DSP chips and derivatives can sometimes fix memory latency, at which point this sort of static scheduling can be useful, though there's still the ratio of branch to arithmetic to deal with.
As an aside, I'm not convinced by their motivating claim that current processors are power-inefficient. x64 / aarch64 / amdgpu seem to get a lot of maths done per watt.
> As an aside, I'm not convinced by their motivating claim that current processors are power-inefficient. x64 / aarch64 / amdgpu seem to get a lot of maths done per watt.
Inefficient in the sense that in a general-purpose high-performance CPU the actual work performed by instructions is practically inconsequential compared to the work performed to manage it's execution.
> As an aside, I'm not convinced by their motivating claim that current processors are power-inefficient. x64 / aarch64 / amdgpu seem to get a lot of maths done per watt.
Why does getting a lot of math done per watt preclude the possibility of a more efficient design? For example, aarch64 is generally more efficient than x64 from a perf/watt metric and GPUs are more efficient for a subset of problems. It’s not hard to believe that existing CPU architectures do not represent the Pareto frontier. For example, x86’s variable length encoding is known to be substandard from an efficiency perspective because the decode frontend can’t extract as much parallelism as a fixed length / aligned instruction set and in today’s machines that would be more impactful to fix than the memory bandwidth saved by a relatively inefficient compression scheme.
Mill is vaporware. Where is the FPGA version that you can play around with? The Reduceron was developed a decade ago and actually existed on FPGAs and it had an edge over contemporary processors like the Pentium 2 in functional programming workloads.
There are modern architectures like Taychium‘s processors that are truly novel and nobody really cares about them. Why exactly would anyone expect the Mill architecture to live up to it's mind share?
That video really isn't giving me the vibe this is any more real than Mill, just better funded. I think they failed to mention how their new CPU will also fix world hunger.
There was a lot to be said for the original patent application process where you had to file an instance of a working machine using the process along with your patent application.
I think for any reasonable version of that rule, an FPGA version would be good enough. And I'm pretty confident that if it was necessary for the patents, they can and would have built basic FPGA versions.
So while there are certainly adjustments to make to the patent system, I don't think that particular rule would have changed anything here.
Yeah, I came here to comment that this sounded very similar to the belt. The comment numbered 3929 on the link you provided is useful as it succinctly explains the difference:
The addressing (STRAIGHT vs Mill) is different: STRAIGHT refers to the generating instruction in time order, whereas Mill refers to the dropped result. In the hardware STRAIGHT uses a scoreboard approach to block for uncompleted instructions, while Mill uses full static scheduling. Some benefits are shared: no renaming, no encoded result registers. Some are peculiar to one or the other: Mill needs no reorder buffer, while straight need not track instruction retire time in the compiler.
Actually, after my third reading, I don't think it does infringe on their patent.
The last comment on the GP link (3958) states: "The STRAIGHT addressing is not a belt because it uses ordinal instruction addressing, while a belt uses ordinal drop. But the new Clockhands addressing is a belt, pure and simple."
But after re-reading the article again, it sounds like it genuinely is an extension of the STRAIGHT system to just add 4 groups of "ordinal instruction addressed" registers rather. It still definitely doesn't fulfil the criteria for "ordinal drop" as described in the comment (by the same author) that I quoted above.
> There are eight callee-saved registers, which are written to the v hand, meaning that when it exits from a function, the values in v[0]–v[7] are not changed.
Any instruction whose destination is a hand will change the offsets of all previous values in that hand. So am I correctly understanding that with this calling convention, every function that includes a loop must end with eight "mv" instructions, to restore those eight callee-saved registers to the "top" of the v hand?
This seems like it would benefit enormously from a special instruction that allows you to decrement a hand's offset by a fixed amount.
That immediately jumped out to me as well. I'm not sure their scheme can easily support a "hand decrement" instruction, either, since then the reused physical register might still have OoO instructions in flight using it and you're forced to stall, like they are doing if they loop around the hand ring buffer. You could have an instruction that pushes all of v[0]-v[7] to memory and restores it, like arm32 ldmia/stmdb, I guess?
There should be several ways to optimize around this without needing new instructions. Choosing different calling conventions for some functions (e.g. PreserveMost in llvm), amortizing the cost over multiple loops by inlining harder, using other hands instead if the register pressure inside the loop is low, ...
Would a CPU still benefit if it supported both a register-renaming mode for backwards compatibility and a clockhands mode for power saving/a wider frontend? Like ARM thumb or x86 32 vs. 64 bit.
The big advantage of this and similar proposals is they replace the massive register file renaming needs with something much more efficient in chip area. It's not just the number of registers/positions, it's that renaming forces a register file with a ton of ports, where chip area grows as the square of number of ports.
So a chip that had both physical structures would be very area inefficient, and this is unlikely to be a win on cost, performance, or power.
I'm not really sure this is true. The reason you need register renaming is because of pipelines and variable execution timings. However, it should be fine to have some single-cycle load/store instructions that move data between the rotating and non-rotating register files - because if those instructions are single cycle, there is no need to renaming as the next instruction knows that the register is already updated.
In some ways, this isn't really needed - you could spill registers to the stack, but having a non-rotating register file means you can avoid actually writing these out to memory. In many ways, the SPARC register file solution would be appropriate here too, as then you completely avoid the notion of caller/callee saved whilst also avoiding actually having to store temporaries on the stack at all, unless a certain function depth is reached.
(EDIT: just re-read the document, and I guess a callee is free to never use the "v hand", and so it wouldn't need to save those registers either, so maybe this is sufficient.)
But I think having a non-rotating register file is useful, otherwise you'll incur penalties for branching code as you'll now either have divergent code paths that factor in the different register offsets, or you'll have a load of code wasting cycles just to move all the registers back where you expect them.
(EDIT EDIT: after thinking about it more, I think the 4 hands approach actually neatly solves many of problems I envisaged - the conditional code paths can just use a different hand and re-converge execution with another hand register file being correct. I think I actually quite like this idea!)
> there is no need to renaming as the next instruction knows that the register is already updated.
Still some complications arising from the second instruction being dependent on the first and needing to be issued to an execution unit after the first one.
You only need a renamer for out-of-order issue - I guess you could execute a backward compatible ISA using only in-order issue. Still, it doesn't strike me as very likely to be implemented in that way.
I think we are talking at cross purposes. I assumed that everyone who has followed the discussion so far knew about in order implementations of a single ISA, which they all were, originally.
it's not just area, it's also powering the machinery. If you could turn it off for workloads that don't need it, you could achieve a reducing in power consumption. It would be better to also save the area, but perhaps a tradeoff if worth it?
Unpowered silicon is great for power management as well. In order to heat up the chip, you'll also need to heat up those dark areas, allowing you to push more power for longer (in comparison with a design with zero spare transistors).
This is another variant of statically schedule lots of code ahead of time, moving work from the hardware into the compiler. Works really well if basic blocks contain many instructions and memory latency is known in advance, at least to within tight bounds, and you put enough effort into the compiler.
Traditionally basic blocks are short and memory latency is all over the place, at which point you really want to schedule things at runtime. Hence CPUs and GPUs - both do a load of nominally avoidable work at program runtime. DSP chips and derivatives can sometimes fix memory latency, at which point this sort of static scheduling can be useful, though there's still the ratio of branch to arithmetic to deal with.
As an aside, I'm not convinced by their motivating claim that current processors are power-inefficient. x64 / aarch64 / amdgpu seem to get a lot of maths done per watt.