4 ms·
I've always wondered how independent µarchs are from ISAs. I mean people do say that Ryzen shares a lot of elements from AMD's ARM K12 project.
by skavi 6y ago
I've always wondered how independent µarchs are from ISAs. I mean people do say that Ryzen shares a lot of elements from AMD's ARM K12 project.
- temac 6y agoWell you have the multiprocessor memory model for example. Technically, you could use a stricter one (from x86) on arm, but that would maybe prevent some non-atomic efficiency gains, and if it's for a platform with competitor chips that do not do that, programs also won't be able to profit from your stricter model (and maybe Arm Holding won't even let you document it); maybe you will be faster on some atomic instructions though (because you have to be fast for even your non atomic ones anyway), but I doubt that would be beneficial in the majority of workloads. Clearly, there can be shared elements, but, if you want something optimized, not everything.
- phire 6y agoARM has a more relaxed memory model that allows you to skip some uarch components. For example, the x86 instruction cache needs to watch for writes to instructions it's executing, while ARM derived CPUs can just ignore those writes. And ARMs fixed length instructions allow apple to just duplication their instruction decoder logic until they are decoding (currently) 7 instructions per cycle. With x86, you have to work out how long each instruction is to know where the next instruction starts. Intel and AMD actually try to decode an instruction starting at every single byte (over 16 bytes) letting the earlier instructions cancel out any incorrect instructions. With this scheme, Intel can only decode 5 instructions per cycle, while AMD are currently doing 4. And they both require certain complex instructions to always go in the first decoder. To overcome this bottleneck, Intel and AMD both cache decoded uops in an L0 cache to speed up tight loops. Intel can do 6 uops per cycle, AMD can max out at 8 uops. Apple can skip all this complexity. Their decoders operate at full speed and there is no need to cache uops. Beyond these two areas, the rest of the CPU core is reasonably ISA agnostic. The scheduling and execution units can stay the same, but the optimal balance of execution units might change based on the ISA. That balance also might change based on the type of code the CPU is expected to execute, and the compiler.
- wolfgke 6y ago> And ARMs fixed length instructions allow apple to just duplication their instruction decoder logic until they are decoding (currently) 7 instructions per cycle. Only the A32 and A64 instruction sets of ARM have fixed 32-bit-length instructions. T32 instructions are either 16 or 32 bits long.
- phire 6y agoTrue. But even decoding a variable length instruction set with just two lengths is far easier than decoding x86. With T32 you just look at bits 15-13. If they are 111, it's a 32bit instruction. If they are anything else, it's a 16 bit instruction. x86 is somewhat insane. Instructions can be any length from 1 to 15 bytes, and thanks to prefix bytes, the bits that specify the length can be found at any byte offset and might be spread over multiple bytes and interact with each other. Even for 15 byte instructions, the 15th byte can tell the difference between "this is a valid 15 byte instruction" or "this instruction is actually 16 bytes long and therefore invalid"
- mojuba 6y ago> while ARM derived CPUs can just ignore those writes Could you elaborate why?
- phire 6y agoOn x86, an instruction is allowed to overwrite the memory for the very next instruction and expect the CPU to pick up the modified instruction and execute it. On modern Superscalar designs, this requires the instruction cache to actively watch for any writes to cachelines it holds and invalidate them. If that cacheline is currently being executed, the core needs to go further. The scheduler needs to decide if the instruction modifing the cacheline is before or after that position in the instruction stream. If it's after, the whole pipeline needs to be flushed and the instruction fetcher reset to the modified instruction and execution restarted. Not a fast operation, but it needs to be supported due to the spec (and legacy code) With ARM, the spec says the CPU is allowed to do whatever it feels like in this sitatuion. The cheapest option is to just ignore the write and execute whatever old code is currently in the instruction cache. But to allow self modify code (and loading of libraries) ARM provides a special "invalidate the instruction cache" instruction which explictly tells the CPU something funky has happened and it need to flush data out of the instruction cache before continuing.