ARM immediate value encoding
alisdair.mcdiarmid.org
alisdair.mcdiarmid.org
Actually, it turned out not to be that good a decision. The generated code is far less compact than x86, and this has costs which outweigh the advantage of simpler instruction decode. CPU speeds increased far faster than memory, so the costs of storing and fetching more instruction data grew larger and larger.
As a result, ARM experimented with other more compact encoding schemes, e.g. Thumb.
It's certainly possible to design a CISC ISA (or maybe even a RISC one) that's optimized for compactness. x86 isn't that, though. Maybe it was in the 16-bit era, in a hypothetical future where BCD instructions were used a lot.
(There are SSDs that do transparent compression/decompression. I wonder if there are RAM chips out there that do the same thing for performance?)
To be fair to ARM, their original decision to stick to fixed size instructions was probably correct at the time, when the limiting factor in performance was entirely CPU, and memory speeds were not so much a bottleneck.
Generally, the thought is that ISA doesn't really affect performance.
I don't really understand their conclusions though. They show that the behaviour of x86 (converted to uOps) and ARM is similar (instructions in flight, etc), but I can't see how their the end result (the i7 is vastly faster, sometimes 25x faster than the ARM A8/A9) can demonstrate that the ARM instruction set is not responsible for some of the performance difference.
The paper certainly demonstrates that there is no performance hit going the other way, i.e. the extra complexity of the x86 instruction is never a bottleneck, and once translated to uOps, the instructions are broadly comparable to RISC. I get that, but I don't get how they can also conclude that the ARM ISA is not a performance limiter. They don't investigate code size or memory/cache performance, for instance.
http://i.stack.imgur.com/daciI.png
I'd expect actually running an i7 at 1GHz vs 3GHz to be far more power efficient than their scaling indicates.
There's some past HN discussion about that paper/an article related to it here:
If you're primarily comparing the two major survivors of this battle, as the interesting paper you linked to does, less competitive ISAs that didn't make the cut would already be removed from serious consideration.
Heck, the great success of both the Intel and ARM ISAs was largely a matter of historical accident than intended design, e.g. the 8086 was designed to be compatible with earlier 8 bit designs and to fit in a 20,000 active gate budget. As I've described elsewhere, the ARM was designed to hit a power dissipation target (which it did by a huge margin), and since then the compact Thumb ISAs have been added to it.
Decoding enough instructions to feed a wide issue machine is really hard on x86 and can require loads of power due to the ISA, while if you have fixed or semi-fixed size instructions (like thumb), it is much easier.
You can design ISAs that are made for wide issue, cheap decoding, and compact encoding at the same time, but unfortunately it required asking questions that just was not available to the MIPS/ARM/x86 designers. Out of order execution superscalar processors just weren't invented yet.
http://www.extremetech.com/extreme/188396-the-final-isa-show...
The x86s have 32K of L1 icache, the ARMs 32K or 16K, and the MIPS Loongson has 64K. Also, the Loongson does not support MIPS16 whereas the ARMs all support Thumb. If you look at the total energy consumed, the MIPS is noticeably worse than x86 or ARM:
http://www.extremetech.com/wp-content/uploads/2014/08/Averag...
In fact, the cache takes so much power that Intel engineers have found it profitable to turn off parts of the cache when in low-power modes; this feature is called Dynamic Cache Sizing and appears in the later Atom series.
It's not that simple. Dynamic power depends on the toggle rate of the flip-flops and the electrical capacitance of the fan-out wires and gates, not on the number of transistors. In a cache, very few storage elements change their state in every cycle, while the decoder performs a lot of work in every cycle.
Except this isn't true for x86-64, because x86-64 instructions are just as large as ARM instructions in practice.
Intel has had a massive advantege in fabrication for a long time.
I say "fall" because ARM had an additional advantage, the market which they were targeting couldn't afford ceramic packages, only plastic, and they didn't have the simulation capability to confirm their 2nd design would hit their power dissipation target (they were in fact using chips from their 1st design), so they were very conservative and hit their target with a very large margin to spare, maybe a factor 10?
So with that extra advantage, and a good business model (better than any competitor at the critical times? Certainly MIPS), they got more and more design wins where power was a consideration. In 2001 at Lucent I worked on a power constrained monster board that provisioned something like 300 modem lines, it had specialized ADI chips to do the heavy lifting, they were controlled by a bunch of ARM chips, and it had one housekeeping MIPS chip that was standard for these boards. And they pretty much own the mobile market that isn't tied to x86 by an existing software base, or that needs more horsepower than they're currently offering.
I found the interview of him I was making my comments from, here's the critical 2 paragraphs (http://queue.acm.org/detail.cfm?id=1716385):
SF The ARM was conceived as a processor for a tethered desktop computer, where ultimate low power was not a requirement. We wanted to keep it low cost, however, and at that time, keeping the chip low cost meant ensuring it would go in low-cost packaging, which meant plastic. In order to use plastic packaging, we had to keep the power dissipation below a watt—that was a hard limit. Anything above a watt would make the plastic packaging unsuitable, and the package would cost more than the chip itself.
We didn't have particularly good or dependable power-analysis tools in those days; they were all a bit approximate. We applied Victorian engineering margins, and in designing to ensure it came out under a watt, we missed, and it came out under a tenth of a watt—really low power.
[1] If I remember correctly, I saw the graph showing this memory-faster-than-CPU in the famous Hennessy&Patterson book, which is somewhat ironic since it quite heavily preaches about the virtues of MIPS.
That isn't true with x86-64. I've measured the average instruction size of x86-64 in the wild and it ends up being almost exactly 4 bytes. REX prefixes add up fast.
My guess is that x64-64 still saves quite a few pages of memory over 64-bit ARM on a large program.
x86_64 size: 5.2M arm64 size: 4.4M
So on at least some large codebases, arm64 looks pretty efficient.
Modern 32-bit arm also have movw and movt, which load the bottom and top 16 bits of a register. Combining the two you can load any 32-bit value in two instructions. Classic 8-bit+rotation immediates are still used for arithmetic immediates though.
ARM64 is different. For arithmetic, you get a 12-bit value with an optional left-shift by 12, for bitwise instructions you get an arbitrary string of 1's at any position you want (including rotated), which turns out to be very useful, while for loading values, just like in modern ARM-32, you load 16 bits at a time using movw, movt and movk to reach the higher parts of a register. You have to string together four of those to load a fully general 64-bit value, but that's pretty rare in practice.
Is the bitmask immediate. Such an immediate is a 32-bit or 64-bit pattern viewed as a vector of identical elements of size e = 2, 4, 8, 16, 32, or 64 bits. Each element contains the same sub-pattern: a single run of 1 to e-1 non-zero bits, rotated by 0 to e-1 bits. This mechanism can generate 5,334 unique 64-bit patterns (as 2,667 pairs of pattern and their bitwise inverse). Because the all-zeros and all-ones values cannot be described in this way, the assembler generates an error message.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc....
I feel like I have a vague memory of a single byte being repeated with some specific pattern for some instruction, but I can't find it anymore.
Of course, being a stack machine, this is easier (no register to address, just a top-of-stack value).
I don't know why the Transputer didn't take off. Probably Occam (which was interesting, but weird). I know of at least one TV set top box that used the T800, but don't know of any other design wins the chip had.
I think for two reasons.
1) "too weird". This eventually dooms all of the goofy architectures like Transputer, IA-64, Transmeta, STI Cell, etc. Nobody wants to deal with something radically different unless there are compelling long-term reasons to do so. Granted, that's a little bit of a chicken-and-egg argument. Without adoption there won't be any long-term existence of an architecture.
2) Support tools and infrastructure. Intel and ARM have an incredible variety of support software. Any new architecture is at a disadvantage unless and until all that supporting stuff is written and works well. This means compilers, IDEs, development hardware, etc. Normally the tools for a new architecture are laughably primitive compared to existing environments. Which puts early adopters at a serious disadvantage.
We're in an x86-64 / ARM duopoly now. Nothing else is really relevant. Do you see anything that could change that in the near future? I sure don't.
Maybe OpenRisc/Risc-V will rise. Who'da thunk in 1990 that Linux would rise?