Live data from Hacker News

Memory access on the Apple M1 processor

lemire.me

261–270 of 278 posts

Re: Memory access on the Apple M1 processor

#261
post #138

Earlier quoted context omitted.

Apple has at most 10% of the computer market and is just one player among many. I am skeptical Microsoft with their 90% dominance would or should be allowed this much power over the industry.

90% dominance of what is increasingly a small niche market. Apple controls a large fraction of the mobile device market, and everything else runs linux.

The fact is outside of the tech scene, most businesses and consumers runs Windows. To say this is a "small niche market" is laughable. Microsoft is everywhere.

Re: Memory access on the Apple M1 processor

#262

Earlier quoted context omitted.

Certainly Apple's processors are far ahead, but they're a full process generation (5nm) ahead of their competitors. They paid their way to that exclusive right through TSMC. I'm sure they'll still come out ahead in benchmarks, but the numbers will be much closer once AMD moves to 5nm. You absolutely cannot fairly compare chips from different fab generations. I don't see many comments hammering this point home enough.…

The 5nm vs 7nm vs 10nm vs whatever nm narrative is highly reminiscent that of clock rate flame wars raging in the tech bubble over a decade ago. Back in the early aughts, when the great engineering was still a thing, alternative CPU designs (DEC Alpha 21264, MIPS 10k/12k, PA RISC, POWER and later UltraSPARC designs) were consistently outperforming any x86 design by at least an order of magnitude or more whilst being…

Sorry, but alternate CPU designs were never outperforming x86 by an "order of magnitude", especially not at a lower clock speed. That is a complete exaggeration. I was around during that time period and can find nothing that supports this. The Alpha was fast, yes, but you're talking 2 to 3x best case with floating point compared to a 2 to 3x cheaper Intel system. I did find some old benchmarks: http://macspeedzone.com/archive/4.0/WinvsMacSPECint.html

UltraSPARC was not very competitive. Those machines were very, very expensive and you didn't get much bang for the buck. They weren't even that fast. The later chips had tons of threads but single threaded performance was pretty bad...

Re: Memory access on the Apple M1 processor

#263
post #175

Earlier quoted context omitted.

My guess is it had to do with limitations tied to the x86_64 instruction set. It doesn't matter how much modifications you do, if you don't start with a good foundation, you're going to be limited to that foundation.

I think the current consensus among experts is that the instruction set is not the limiting factor. Modern x64 microprocessors have a separate front-end that handles instruction decoding. These instructions are decoded to internal proprietary "micro-ops". The internal buffers and actual execution units see only these µops. One can measure where the bottlenecks are, and it's rare to find that the front-end is the bott…

> I think the current consensus among experts is that the instruction set is not the limiting factor.

Yes and no. Yes, because modern super scalar CPU's don't execute the instructions directly, but rather use a different instruction set entirely (the "micro-ops") and effectively compile the native instructions into that. This makes them free to choose whatever micro-ops they want. Ergo the original instructions don't matter.

But .... that means there is a compile step now. For a while that was no biggie - it can pipelined if the encoding is complex. But now the M1 has 12 (iirc) execution units. In the worst case that means they can execute 12 instructions simultaneously, so they must decode 12 instructions simultaneously. The is a wee exaggeration as it isn't that bad. In reality the M1 appears to compile 8 instructions in parallel.

This is where the rot sets in for x86. Every ARM64 instruction is 32 bits wide. So the M1 grabs 8 32 bit words, compilers them in parallel to micro-ops. Next cycle, grab another 8 32 words, compile them to micro-ops, and so on. But the x86 instructions can start on any byte boundary, and can be 1 to 16 bytes in length. You literally have to parse the instruction stream a byte at time before you can start decode it. In practice they cheat a bit, making speculative guesses about where instructions might start and end, but when you're being compared to someone who effortlessly processes 32 bytes at a time that's like pissing in the wind.

So the instruction set may not matter, but how you encode that instruction set does matter, at lot. Back in the day, when there we few caches and every instruction fetch cost memory accesses, you were better off using tricks like using one byte for the most common instructions to squeeze the size of instruction stream down. That is the era x86 and amd64 hark from. (Notably, the ill-fated Intel iAPX 32 took it to an extreme, having instructions start and end on a bit boundary.) But now with execution units operating in parallel, and on chip caches putting instruction stores on chip right beside the CPU's, you are better off making storage size worse in order to gain parallelism in decoding. That's where ARM64 harks from.

It's interesting watch RISC-V grapple with this. It's a very clever instruction set encoding that scales naturally between different word sizes. This also naturally leads to a very tight, compressed instruction set. But in order to achieve that they've got more coupling between instructions than ARM64 (but far, far less than x86), and any coupling makes parallelism harder. Currently RISC-V designs are all at the small, non-parallel end, so it doesn't effect them at all. In fact at the low power end it's almost certainly a win for them. But I get the distinct impression the consensus of opinion here on HN is it will prevent them from hitting the heights ARM64 and the M1 achieve.

Re: Memory access on the Apple M1 processor

#264
post #158

Earlier quoted context omitted.

This isn’t specific to the M1 but I tap about cache lines in my last QCon presentation (where I also suggested that a 128b cache line wasn’t far away): https://www.infoq.com/presentations/microarchitecture-modern... However the speed benefits come from a much larger L1 cache and the fact that the ram is in the same chip which will reduce latency that is the benefit for most of it. The program (instruction) cache is a…

This post says that the m1 has a 128 byte cache line size. So that time has arrived! https://news.ycombinator.com/item?id=25660769

Yup, my presentation was back in March 2020 and the M1 came out later in the year — sooner than I was expecting, TBH; I thought that it was a couple of years out when I said it :-)

Re: Memory access on the Apple M1 processor

#265
post #246

Earlier quoted context omitted.

Intel does lots of contributions across the OS (Linux and glibc) to compilers including their own (gcc, icc, ispc, etc). Their problems aren't their ability, it's that Intel is poorly managed and internal groups are constantly fighting with each other. Also, compiler support for CPUs is very overrated. Heavy compiler investment was attempted with Itanium and debunked; giant OoO CPUs like Intel's or M1 barely care abo…

> Intel does lots of contributions across the OS (Linux and glibc) to compilers including their own (gcc, icc, ispc, etc). Their problems aren't their ability, it's that Intel is poorly managed and internal groups are constantly fighting with each other. I wasn't just talking about Intel but the concept of separate CPU and compiler vendors in general. Intel contributes a ton of open source but even if they were perfe…

> Itanium failed because brilliant compilers didn't exist and it was barely faster even with hand-tuned code, especially when you adjusted for cost, but that doesn't mean that it doesn't matter at all.

What you said is true for libraries, I just don't think it's true for compiler optimizations. Even Apple's clang just doesn't have any new optimizations that work on their own; there are certainly new features but they're usually intrinsics and other things that need to be adopted by hand. They thought this would happen (it's what bitcode was sold as doing) but in practice it has not happened.

Re: Memory access on the Apple M1 processor

#266
post #175

Earlier quoted context omitted.

I think the current consensus among experts is that the instruction set is not the limiting factor. Modern x64 microprocessors have a separate front-end that handles instruction decoding. These instructions are decoded to internal proprietary "micro-ops". The internal buffers and actual execution units see only these µops. One can measure where the bottlenecks are, and it's rare to find that the front-end is the bott…

> I think the current consensus among experts is that the instruction set is not the limiting factor. Yes and no. Yes, because modern super scalar CPU's don't execute the instructions directly, but rather use a different instruction set entirely (the "micro-ops") and effectively compile the native instructions into that. This makes them free to choose whatever micro-ops they want. Ergo the original instructions don't…

Great comment, and great accurate explanations of complex stuff! I'm still going to disagree with the conclusion, though. Yes, x64 has to jump over horrible hurdles to prevent instruction decode from being a bottleneck. Yes, this makes for more complex processors, possibly with poorer performance per Watt. But I'm asserting (in my reasonably expert opinion) that the ridiculous contortions currently in use are (in almost all cases) adequate to prevent the instruction decoder from being the bottleneck.

What's missing from your description is the extra level of decoded µop cache between the decoder and instruction queue on modern Intel chips. In a tight loop, this pre-decoder kicks in and replays the previously decoded µops at up to 6 per cycle. It's a mess (and complicated enough that Intel needed to disable part of it with a microcode update on Skylake) but it provides enough instruction throughput that the real bottleneck is almost always elsewhere. Specifically, the 4-per-cycle instruction retirement limit almost always maxes out my attempts at extremely tight loop code earlier than instruction decoding.

Which is to say, you are right about how much easier it is to decode ARM64 instructions, but I think you are wrong that decoding x64 is in-practice a limiting factor for performance. If you have a non-contrived example to the contrary, I'd love to see it.

More details here: https://en.wikichip.org/wiki/intel/microarchitectures/skylak...

And in this nice blog post: https://paweldziepak.dev/2019/06/21/avoiding-icache-misses/

Re: Memory access on the Apple M1 processor

#267
post #20

Earlier quoted context omitted.

This seems to be a recurring theme with the M1, and one that, in a sense, actually baffles me even more than the alternative. There is no "magic" at play here, it's just lots and lots of raw muscle. They just seem to have a freakishly successful strategy for choosing what aspects of the processor to throw that muscle at. Why is that strategy simultaneously remarkably efficient and remarkably high-performance? What en…

The big "enabler" was their mass-purchase of 5nm lithography across the board. Even still though, 4ghz*8c isn't anything new, and isn't really that remarkable besides the low TDP (which is incidentally dwarfed by the display, which draws up to 5x more power than the CPU does). I think the big issue is that Apple has painted themselves into a corner here: ARM won't play nice with the larger CPUs they want to make, and…

"the display, which draws up to 5x more power than the CPU does" - wat? Apple-supplied monitoring tools report that M1 under full load (all CPU and GPU cores) can draw over 30 watts. Laptop displays don't consume 150 watts. If anything, the displays in either of the M1 portables likely consume about 5 times less than 30W, even at full brightness.

"ARM won't play nice with the larger CPUs they want to make" - wat? Apple holds an architectural license. This means they paid a lot upfront a long time ago and therefore have a more or less perpetual right to design their own Arm cores without input from Arm.

"a competent graphics solution" - Also wat? M1 has an excellent GPU. It doesn't compete with discrete GPUs that use 300 watts, but that's fine: M1 is the chip for entry level Macs, designed for the smallest and lightest segments of their notebook line. And in that product segment, it has been every bit as much a revelation as the CPU. It's very fast, and uses little power given the performance.

What exactly do you think is going to happen when they scale that basic GPU design up? Despite your dismissiveness, in modern silicon architecture energy efficiency is incredibly important: for any given power budget, the more efficient you are the more performance you can deliver. The performance Apple gets out of about 10W on M1 suggests they'll have few problems building a larger GPU to compete with Nvidia and AMD discrete GPUs.

Re: Memory access on the Apple M1 processor

#268
post #141

Earlier quoted context omitted.

(base) Coding % cc -mnative two-three.c clang: error: unknown argument: '-mnative' (base) Coding % cc -v Apple clang version 12.0.0 (clang-1200.0.32.28) Target: x86_64-apple-darwin20.2.0 Thread model: posix

It's spelled "-march=native" in gcc and "-arch x86_64h" in clang. It doesn't make much difference though, autovectorization doesn't work very well and there is not a lot of special optimization for newer x86 CPUs.

All recent Intel Core-i microarchitectures require using full vector width loads to max out L1d bandwidth, because the load/store units don't actually care about the width of a load, as long as it doesn't cross a cache line (in which case the typical penalty is an additional cycle).

Only using 128 bit wide instructions on a core that has 512 bit hardware results in 4x less L1d bandwidth.

Re: Memory access on the Apple M1 processor

#269
post #247
post #240

Earlier quoted context omitted.

I just ran it again, and got more or less the same results: N = 1000000000, 953.7 MB starting experiments. two : 29.7 ns two+ : 36.5 ns three: 43.8 ns This surprises me. Normally, it does very well in most benchmarks I run. Looking a little closer at the script, it loads numbers from "random", a vector of 3 million `Int` (this is hard coded, separate from `N`). This vector is about 11.4 MiB. The Tiger Lake CPU has 12…

The caching of the random[] array (almost) shouldn't matter, as the access is sequential. I'm wondering if the difference is the the number of active memory channels. How many channels does your respective computers support? Do you have enough RAM installed so all channels are in use? Are you able to do a RAM bandwidth test by some other means to verify? Another possibility is that for some reason the base latency is…

I'll run the pointer-chasing version later. Thanks

Re timing issues: I am on Linux.

Re: Memory access on the Apple M1 processor

#270

Earlier quoted context omitted.

That's bizarre. As if CPU vendors were unable to run "realistic" workloads. If they truly aren't, that's because they are unwilling and then they are designing for failure and Apple can just eat their lunch.

As a data scientist, I feel this. Intel and AMD don't own an OS or an app store, and you might be surprised how hard it is to get good data. Data is the new gold. If a company that can corner a piece of the market, they can collect data no one else can, and from that companies are often forced to partner or they can't properly provide services that will keep them competitive.

> Intel and AMD don't own an OS or an app store

They could run their benchmarks on the Debian repository and it would probably be representative enough.

If they haven't done so, perhaps because it seemed tedious or unimportant, well, that mistake would be on them.

Post reply on HN