I can't find the exact tweet, but it was stated by Apple engineers that the retain and release operations are faster on Intel x86 translation than on standard Intel x86.
-
1@DocBrown Clearly he's not, he's asking for more information.– AlexanderCommented Nov 15, 2020 at 6:08
-
1@Alexander-ReinstateMonica: the question title pretends the OP are believing what those Apple engineers were writing (if they did so, which we cannot verify). But even if the OP could find the reference (which they should before asking here), this would probably end up in a question of the type Discuss this ${blog}, which the community here usually does not like.– Doc BrownCommented Nov 15, 2020 at 7:58
-
Entirely believable. The x86 design is 20/35/42 years old, depending on how you count. It's such a bad model for actual hardware that even x86 CPUs translate machine code on the fly to their internal microcode, but using hardware-based decoders. ARM is technically superior to x86 in many ways, including in particular its memory model. So it's unsurprising that some performance characteristics would carry through an emulation layer.– amonCommented Nov 15, 2020 at 10:49
-
According to rumors on Twitter, Apple Silicon contains special hardware implementations that emulates memory ordering behavior of x86 architecture. (link 1: Hacker News) (link 2: Twitter) (link 3: someone's Github repo) Without such hardware enablement, x86 emulation can be slow, due to the extra burden of emulating those to ensure correct execution of x86 code. Apple's implementation may be aided by the fact that everything is on a single piece of silicon.– rwongCommented Nov 15, 2020 at 14:30
2 Answers
Rosetta 2 employs Just-In-Time compilation with dynamic optimization, just like, for example, the Oracle HotSpot JVM (and most others as well, e.g. IBM J9 / Eclipse OpenJ9), the Microsoft .NET CLR, all mainstream ECMAScript implementations (GraalJS, V8, SpiderMonkey, JavaScriptCore), the PyPy, GraalPython, IronPython, and Jython Python implementations, the Rubinius, IronRuby, JRuby, TruffleRuby, and YARV Ruby implementations, and many more.
Since a dynamic optimizer can simply inspect the current program state and observe the program behavior, impossibility results for static analysis, such as the Undecidability of the Halting Problem or Rice's Theorem do not apply, and thus the Rosetta 2 dynamic optimizer can perform optimizations that the original Swift or Objective-C compiler could not. So, it is not surprising that the code may be more optimized and thus may be faster for certain types of operations.
You would probably be able to achieve the same by running a modified version of Rosetta 2 that compiles from AMD64 to AMD64 on an Intel Mac, or a modified version that compiles from AArm64 to AArm64 on an Apple Silicon Mac, or by changing Swift and Objective-C from an ahead-of-time compiled implementation to a JIT-compiled implementation.
The fact that JIT compilation with dynamic, speculative, and adaptive optimizations can yield large performance benefits has long been known in the dynamic language communities, especially Smalltalk and Lisp. (For example, Oracle HostSpot JVM is actually just a modified Smalltalk VM, IBM J9 was built by IBM's Smalltalk team based on their Smalltalk VM, Google V8 is based on a Smalltalk VM (actually the same one as Oracle HotSpot JVM is).)
But in the late 1990s, for the first time, the knowledge also spread in the C, C++, and assembly communities as well as the CPU community. Intel and HP were working on a new CPU architecture called IA-64, which would be a replacement for HP's PA-RISC architecture as well as Intel's IA-32 architecture (at least on servers and workstations). The CPU bus was kept mostly compatible with PA-RISC, so that it could be used as a drop-in replacement for HP mainframes, but of course, the ISA was completely different.
So, in order to enable their customers a smooth transition from PA-RISC to IA-64, HP developed a dynamic binary translator based on JIT compilation with dynamic optimization. They wanted to benchmark this translation system, but there weren't any IA-64 chips yet. However, they realized, that if they built a PA-RISC backend for the translator, they could still benchmark it, since it would still do all the same work: parse the PA-RISC binary, analyze it, optimize, and then generate optimized machine code, the only difference being that the generated machine code is also PA-RISC instead of IA-64.
In fact, because the frontend and backend are the same, they could make a direct comparison of code running natively in PA-RISC, and code running in the translator on the exact same system, which would allow them to accurately measure the overhead and slowdown of the translator. And so they did measure it, and they found that the slowdown was … negative! In other words, it was a speedup.
This was the well-known Dynamo project.
So, in short: dynamic optimization can perform optimizations that static optimization cannot, so it is at least believable that the statement could actually be true.
-
I thought Rosetta 2 uses static compilation. Take a whole application, either when it is installed or just before it is launched for the first time, translate it from Intel code to ARM code. Commented Nov 17, 2020 at 1:06
-
It can do both, from what I understand. A third pathway, from what I understand, is that apps that are submitted to the App Store are required to be submitted with LLVM bitcode, so it could theoretically also be compiled on Apple's servers. Commented Nov 17, 2020 at 7:52
First, the M1 processors seem to have significantly higher speed than equivalent Intel processors, so retain / release would run faster after translating Intel to ARM code unless the translated code was significantly worse.
But these two operations are used an awful lot. And Apple has written the code for them, so it's quite possible that they don't get translated using the general purpose translator, but that the translator will recognise the code and translate it to the optimal ARM code for this purpose.
The same is likely true in other situations; if your code calls low-level code written by Apple, that code might be not translated, but directly replaced with equivalent optimised ARM code. And if you look at how much money Apple makes from devices with ARM processors vs. devices with Intel processors, the existing ARM code might be better than the existing Intel code.
And lots of libraries are part of the OS itself, like the Standard C, C++, Objective-C and Swift libraries, so they are not going to be translated at all, but the original ARM libraries will be used.
PS. Today some benchmark results have released comparing Macs with M1 processor running emulated x86 code with Intel Macs - the M1 processor beats any Intel-based Mac in single threaded performance.