10 ms·
How many x86 instructions are there? (2016)
- mobilio 6y agoIn short - endless battle between RISC or CISC.
- kingsuper20 6y agoOh well, there's RISC and there's RISC. I always think of the AMD 29000.
- mobilio 6y agoOr i860 & i960?
- kingsuper20 6y agoI mentioned the 29k since (as I remember, it's been a while) it didn't have a multiply instruction.
- Symmetry 6y agoThese days RISC is mostly about regular encoding of instructions which don't present challenges to doing precise interrupts on a deeply pipelined machine rather than just few instructions per se.
- bogomipz 6y agoWhat do you mean by "precise" interrupts here? Do some types of interrupts cause worse pipeline stalls than other types? Are the interrupt handlers in RISC faster because of more efficient decoding? Is that the issue?
- Symmetry 6y agoNo, it's just that the fact that RISC didn't have any load-op-store instructions made it easier to pipeline them back in the day while still being able to handle interrupts as if they executed one instruction at a time and there was one instruction that had executed while the following one hadn't executed at all. That's possible to do with CISC architectures, of course, we do it all the time these days. But back in the day being able to implement that easily-ish in a reasonable number of transistors were a big factor in early RISC processors having so much better performance than the CISCs of the time. In the modern day it mostly just means that you can implement fancy out of order schenanigans with a bit fewer engineer-years than non-RISC ISAs.
- bogomipz 6y agoThanks these are both very helpful and good bits of historical perspective as well. Cheers.
- zsmi 6y agoThis is the classic definition https://dl.acm.org/doi/10.1109/12.4607 https://dl.acm.org/doi/10.1109/12.4607 "An interrupt is precise if the saved process state corresponds to a sequential model of program execution in which one instruction completes before the next begins. In a pipelined processor, precise interrupts are difficult to implement because an instruction may be initiated before its predecessors have completed."
- snvzz 6y agoEndless? It ended a long time ago. RISC won. There hasn't been any new CISC architecture worth mentioning in decades.
- TwoBit 6y agoARM has all these variations which make it seem as complicated as x86, but they are distict variations and future CPUs can for example drop 16 bit Thumb fairly clearly.
- api 6y agoIt's way easier to determine instruction length on ARM. It's usually fixed. That eliminates a lot of brute force thrashing that X86 decoders have to do. It doesn't impact transistor count all that much on a huge modern CPU but it saves a decent amount of power. It's one of the things that factors into why ARM is so power efficient. ARM has also been willing to drop older optional legacy stuff like Java oriented instructions that almost nobody used and Thumb. X86 supports nearly all legacy opcodes, even things like MMX and other obsolete vector operations that modern programs never use.
- thechao 6y agoIt's not that variable length is expensive, it's that variable length the way Intel does it is expensive. For instance — not that this is a good idea — you could burn the top 2b to mark instructions as 2/4/6/8 bytes (or whatever) in length. Then you can have your variable-width-cake-and-eat-your-fast-decode-too.
- richardwhiuk 6y agoVariable length is always going to restrict the parralelism of your instruction decode (for a given chip area/power/etc cost).
- thechao 6y agoOnly because a single instruction would take the "space" of multiple instructions in the I$-fetch-to-decode. The idea with variable-length encodings is that, for example, an 8B encoding does more than twice the work of a 4B encoding, so you lose out on the instruction slot, but win on the work done. I mean ... that's the theory.
- FpUser 6y agoI feel sudden urge to write some assembly for fun. Have not done it for at least a couple of years I think.
- magicalhippo 6y agoThen when checking the results are half the speed of what the compiler spits out and the fun is gone. At least that's what happens to me...
- f00zz 6y agoThat's why it's more fun to try to optimize for size
- kingsuper20 6y agoI've always been able to beat the compiler, and that's usually after trying to optimize using C. Admittedly, it's a whole lot harder to understand what's fast than it used to be. Access to SSE has it's own benefits. It's been a problem (optimizing) for some time though. I remember it being some work to beat the compiler on the i960CA. OTOH, I seem to remember the i860 being not-so-great and for sure the TI C80 C compiler was downright awful (per usual for DSPs).
- magicalhippo 6y agoBack in the Pentium 1 and earlier days I could beat the compiler. But then it got hard. And it changes so often, instructions that are fast on one CPU are not so fast on the next one, and vice versa. Not to mention branch prediction and out-of-order execution makes it very difficult to meaningfully benchmark. Is my code really faster, or just seems like it because some address got better aligned or similar. I've gotten significant speed gains in certain projects by simply replacing certain hand-optimized assembly in libraries (ie not my code) with the plain C code equivalent. The assembly was probably faster 10-15 years ago, but not anymore...
- mhh__ 6y ago
- gbrown_ 6y agoHow about undocumented instructions? Sandsifter[1] is an interesting project and the video from BlackHat[2] is a good watch. There's also a previous discussion of it on HN[3]. [1] https://github.com/Battelle/sandsifter https://github.com/Battelle/sandsifter [2] https://www.youtube.com/watch?v=KrksBdWcZgQ https://www.youtube.com/watch?v=KrksBdWcZgQ [3] https://news.ycombinator.com/item?id=18179212 https://news.ycombinator.com/item?id=18179212
- sandinmyjoints 6y agoVery cool project! Thanks for the pointer.
- da_big_ghey 6y agoyes and sansdifter are continue finding more, recent undocumented microcode modify instruction are find with it.
- stevemk14ebr 6y agoAlso see https://blog.can.ac/2021/03/22/speculating-x86-64-isa-with-one-weird-trick/ https://blog.can.ac/2021/03/22/speculating-x86-64-isa-with-o...
- gbrown_ 6y agoAh cool, seems I missed that when it appeared on HN a few weeks back. Thanks for the pointer.
- davidkuhta 6y ago> To not leave you hanging: Intel has an official x86 encoder/decoder library called XED. According to Intel’s XED, as of this writing, there are 1503 defined x86 instructions (“iclasses” in XED lingo), from AAA to XTEST (this includes AMD-specific extensions too, by the way). Straightforward, right? Hopefully this will have either saved you a click or validated your time in reading the article.
- anyfoo 6y agoCurious, does anyone actually care about the actual number primarily? I thought pretty much everyone who clicks on an article with that title would do so because they are interested in the insights gathered when getting to that number.
- wglb 6y agoIf you are writing a disassembler or binary program decoder, such a number will help you be sure that you enumerate all the instructions.
- account4mypc 6y agoi think if you were writing such a program, this article would show that using such a number is a much more complicated idea than it sounds
- Out_of_Characte 6y agoEnumerating all instructions would be usefull to check wether you can decode all legal instructions.
- saagarjha 6y agoThe issue is that the list of all legal instructions is hard to define.
- ketralnis 6y ago
- johnklos 6y agoMore than 1,500! Holy cow! While having instructions for everything that are slow in early models but can be significantly improved in silicon over time is one way to look at CISC, I genuinely wonder how much silicon is spent on instructions that are so rarely used they'd be better in software. Or to ask another way: how many instructions are in billions of x86 cores that rarely if ever get used? Hmmm...
- dreamcompiler 6y agoI'd also be curious to discover how many distinct x86 instructions gcc can even emit? I expect the answer is "a lot less than all of them."
- kingsuper20 6y agoI mostly just think of the test set they must make use of at Intel. It makes my head hurt. Maybe you end up with a wad of legacy code so large that no one knows how it really works. That ends up being the real definition of the part.
- Someone 6y agoIf you cheat: all of them. GCC supports in-line assembly. Of course, that’s not an interesting observation. It gets (somewhat) interesting when you realize that one may inadvertently include in-line assembly. Do you call including system headers that happen to contain inline assembly cheating? Including headers for a standard C library? Compiling with old-fashioned compiler flags (for example to generate FPU instructions for the x87)?
- saagarjha 6y agoProbably a couple hundred at most, and for common programs several dozen.
- kijiki 6y agoTried it out on Debian Bullseye x86_64: $ objdump -w -j .text --no-show-raw-insn -d /usr/bin/emacs-gtk | egrep '^ *[0-9]+:' | awk '{print $2}' | sort | uniq | wc -l 130 $ objdump -w -j .text --no-show-raw-insn -d /bin/ls | egrep '^ *[0-9]+:' | awk '{print $2}' | sort | uniq | wc -l 97 $ objdump -w -j .text --no-show-raw-insn -d firefox-bin | egrep '^ *[0-9]+:' | awk '{print $2}' | sort | uniq | wc -l 136
- optimalsolver 6y agoAlternate instructions here :-) https://paws.kettering.edu/~jhuggins/humor/opcodes.html https://paws.kettering.edu/~jhuggins/humor/opcodes.html
- xony 6y ago6000 ? cache can't effectively handle the burden of the decoder propagation delays . compiler writer might not be using even 20% of the total instructions. except backward compatibilty its useless architecture
- hnmullany 6y agoNow ask how many unique x86 instructions do standard compilers emit...
- snvzz 6y agoThe only real answer is: Too Many. This complexity is pushed down to operating systems, compilers, assemblers, debuggers. It ends up causing brutal human time overhead throughout the chain, and its cost effectively prevents security and high assurance. This more than justifies moving away from x86 into RISC architectures, such as the rising open and royalty-free RISC-V.
- WalterBright 6y agoBack in the 70s, a friend of mine said he loved the Z80 instruction set the best. I replied that it was the most complicated and kludgy one. He laughed and said the complexity allowed his code to shine above others and he got paid more. Of course, these days the Z80 instruction set looks trivial :-)
- saagarjha 6y agoThere is complexity, but it’s not nearly as large as you claim it is, nor does RISC magically resolve the issues you’ve brought up.
- deepspace 6y ago> This complexity is pushed down to operating systems, compilers, assemblers, debuggers. Is that really true though? In my experience, the amount of complexity in a layered system is roughly constant, and if you make one layer simpler, you have to make another more complex. I would expect that compiler for a RISC architecture, for example, needs to do a lot of work figuring out which set of 'simple' instructions encode an intent most efficiently. It also needs to deal with instruction scheduling and other issues that a RISC compiler does not care about.
- fruity123 6y agoThe legacy of variable length x86 is why Intel will always struggle now to keep up with ARM chips and Apple’s M1.
- floxy 6y agoI still love the 33 instructions in the Microchip PIC instruction set. https://www.microchipdeveloper.com/8bit:bl-instruction-set https://www.microchipdeveloper.com/8bit:bl-instruction-set
- loadzero 6y agoAn interesting (if horrifying) exercise: $ ndisasm -b 64 /dev/urandom
- dang 6y agoPast related threads: How Many X86-64 Instructions Are There Anyway? - https://news.ycombinator.com/item?id=14233296 https://news.ycombinator.com/item?id=14233296 - April 2017 (133 comments) How many x86 instructions are there? - https://news.ycombinator.com/item?id=12358050 https://news.ycombinator.com/item?id=12358050 - Aug 2016 (39 comments) Does a compiler use all x86 instructions? (2010) - https://news.ycombinator.com/item?id=12352959 https://news.ycombinator.com/item?id=12352959 - Aug 2016 (189 comments) How Many X86-64 Instructions Are There Anyway? - https://news.ycombinator.com/item?id=11535178 https://news.ycombinator.com/item?id=11535178 - April 2016 (1 comment)
- userbinator 6y agoAnd by the way, I used x86 as an example here, but don’t believe for a second the same thing doesn’t apply to, say, the ARM chip in your phone. Modern ARM chips support multiple encodings and also rank over 1000 instructions if you count them at the same level of granularity as XEDs “iforms”. Indeed, those who think x86 is complex should also take a detailed look at the ARM64 instruction set, particularly its instruction encoding. If you thought making sense of x86 instruction encoding was hard, and that a RISC might seem simpler, AArch64 will puzzle you even more. To use the MOV example, the closest ARM equivalent might be the 40 variants of LD, which the reference manual (5000+ pages) enumerates as: LDAR, LDARB, LDARH, LDAXP, LDAXR, LDAXRB, LDAXRH, LDNP, LDP, LDPSW, LDR (immediate), LDR (literal), LDR (register), LDRB (immediate), LDRB (register), LDRH (immediate), LDRH (register), LDRSB (immediate), LDRSB (register), LDRSH (immediate), LDRSH (register), LDRSW (immediate), LDRSW (literal), LDRSW (register), LDTR, LDTRB, LDTRH, LDTRSB, LDTRSH, LDTRSW, LDUR, LDURB, LDURH, LDURSB, LDURSH, LDURSW, LDXP, LDXR, LDXRB, LDXRH. Some, like LDP, are then further split into different encodings depending on the addressing mode. My suspicion is that to achieve acceptable code density with a fixed-length instruction encoding, they just made the individual instructions more complex. For example, the add instruction can also do a shift on one of its operands, which would require a second instruction on x86.