The most fundamental difference between an M1 Mac and all the previous Macs, since they switched to using Intel in 2006, is the processor. The eight cores inside an M1 can’t run code which has been compiled for Intel processors, because the instructions (and more) are different. If M1 Macs could only run apps built for its ARM cores, then they’d have a limited market, so Apple has engineered a temporary solution branded as Rosetta 2. (The original Rosetta had the same task during the transition to Intel.) It’s temporary in the sense that there will come a time when support for Rosetta 2 will be discontinued.
Rosetta isn’t a Virtual Machine (VM), which merely provides a layer to work between different operating systems, and can’t run across different processor architectures. Neither is it an emulator, which provides a virtual processor and is normally painfully slow, as we experienced with PC emulators on PowerMacs in the past. What it does is take the Intel code to be run on an M1 and translates it from Intel to ARM code, before the code is going to be run. When you then come to run that app or tool, it runs almost as fast as on an equivalent Intel processor, and experience with Rosetta 2 confirms this: performance on an M1 Mac is comparable in most cases with that on an equivalent Intel Mac, sometimes even better.
If you look inside macOS, or in the log, you won’t see Rosetta, as internally it’s known as OAH. All its components are stored on the Data volume, not in the sealed System, as it’s only installed on demand, and can be updated outside of normal macOS updates. Its executable code is thus stored in the path /Library/Apple/, with its components in /usr/libexec/oah, and in /usr/share/rosetta.
It consists of a Launch Daemon, run by com.apple.oahd.plist, and its root helper, which provide the
oahd service. As far as I can tell, this is the only part of it which you can see in action in the log. These components are all small, but in extremes of use OAH can consume a lot of memory and CPU when called on to translate very large Intel executable code files.
Apple is a bit vague as to when OAH actually performs translation, but whenever possible this is completed well before the code is required to be run. For some apps, this may occur when they’re installed on the M1 Mac, but it can also be delayed until launch time. One way to observe this is to open a Universal App with the option to Open using Rosetta ticked (in the Finder’s Get Info dialog).
While Launch Services and other macOS subsystems are preparing to launch the app, you should see three small entries in the log.
Aot lookup request for <private>
marks the request to see if there’s already a cached copy of the translated code. If there isn’t, then
oahd continues with the process of translation, reporting
Translating image <private> -> <private>
Once that’s completed, that’s reported in the log with
Translation finished for <private>
Typical translation time for a minimal 242 KB Universal binary, with a little more than 100 KB of Intel executable to be translated, is less than 0.0125 seconds.
When that Intel code is being run, its entry in the Launch Services app information dictionary records LSArchitecture as “x86–64” rather than “arm64”, which is just about the only thing that will tell you what has occurred.
What happens here is that the whole of the app’s Intel executable is loaded into memory, passed to OAH, which translates its executable code into ARM instructions, and hands that back to be run. For a small app, this can be accomplished while Launch Services and other subsystems are preparing to launch the app. For more substantial apps, that may require a lot of code to be loaded into memory, considerable translation work, and a significant delay in launching – hence the aim to perform this before the user needs it.
On an M1 Mac, you can readily tell different types of app apart from their Get Info dialog. Most current apps should be Universal, in that they contain complete executable code to run on both Intel and M1 Macs.
Their Get Info dialogs contain a checkbox which allows you to force them to be opened using Rosetta. Older apps which don’t yet support running native on M1 Macs are reported as being Intel apps.
You will also start to come across the first apps which can only run on an M1, so are identified as Apple Silicon apps.
Being able to force an app to run using Rosetta has its uses. One of the rules for M1 Macs is that you can’t mix Intel and M1/ARM code in the same process. If an app is going to load code modules dynamically, then those too must be run using the same architecture. Rosetta translation applies to an entire process, and you can’t mix and match code within any process.
If your app does need to load code modules which are still Intel-only, then you may need to force it to be opened in Rosetta, or those Intel-only modules may not be available when it’s running. There may also be occasions when you want other loaded code to run in Rosetta: some tools and executables work differently on the two architectures, and it may be advantageous to be able to get Intel results on an M1 system. One example of this is any code which uses Mach Absolute time, which is quite different between the two architectures. An app run in Rosetta translation is given Mach ticks equivalent to one every nanosecond; M1 native Mach ticks are incremented every 41.67 nanoseconds instead.
There are three types of Intel code which can’t be run using Rosetta:
- kernel extensions, which is just as well as most are getting old;
- virtualisation environments like Parallels Desktop and VMware;
- code which requires specialist Intel vector instructions or processor features, which is rare.
The fundamental requirement for any app or tool to translate in Rosetta and run successfully on an M1 Mac is that it must be wholly 64-bit, and fully compatible with Big Sur running on Intel Macs. Unfortunately, this excludes all those apps which can only be run in Big Sur inside a Mojave virtual machine, which includes Adobe CS6 and other stalwarts which are still in wide use despite their age.
Finally, unless an M1 Mac has already used Rosetta, it shouldn’t be installed, and it’s only downloaded and made available if it’s needed. Many users will want to get it installed earlier: to do this, all you have to do is run an app which requires translation, either an older version which isn’t a Universal App, or by running that app (temporarily) using Rosetta. If you want a convenient script to preload Rosetta, Rich Trouton provides one on Der Flounder blog.
Further information about Rosetta for developers is here.