Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

There is no hardware in the M1's for x86 emulation. Rosetta 2 does on the fly translation for JIT and caches translation for x86_864 binaries on first launch.

Docker for Mac runs a VM, inside that VM (which is Linux for ARM) if you run an x86_64 docker image it will use qemu to emulate x86_64 and run Linux Intel ELF binaries as if they were ARM.

That means that currently using Docker on macOS if there is a native ARM version available for the docker image, it will use that, but it can and will fall back to using x86_64 docker images.

That already works as-is. There is no hardware emulation though, it is all QEMU doing the work.



That said, x86_64 images that require QEMU are much buggier than pure arm64 images. Terraform's x86_64 image, for example, will run into random network hangups that the ARM image doesn't experience. It was bad enough for me to maintain my own set of arm64 Terraform images.


"There is no hardware in the M1's for x86 emulation. Rosetta 2 does on the fly translation for JIT and caches translation for x86_864 binaries on first launch."

This is not quite correct.

First, as I understand it anyways, Rosetta 2 mostly tries to run whole-binary translation on first launch, rather than starting up in JIT and caching results. It does have a JIT engine, but it's a fallback for cases which a static translation can't handle, such as self-modifying code (which is to say, any x86 JIT engine).

Second, there is some hardware! The CPU cores are always running Arm instructions, but Apple put in a couple nonstandard extensions to alter CPU behavior away from standard Arm in ways which make Rosetta 2 far more efficient.

The first is for loads and stores. x86 has a strong memory ordering model which permits very little program-visible write reordering. Arm has a weaker memory model which allows more write reordering. If you were writing something like Rosetta 2, and naively converted every memory access to a plain Arm load or store, the reorderings permitted by Arm rules would cause nasty race conditions and the like.

So, Apple put in a mode bit which causes a CPU core to obey x86 memory ordering rules. The macOS scheduler sets this bit when it's about to pass control to a Rosetta-translated thread, and clears it when it takes control back.

The second mode bit concerns FPU behavior. IEEE 754 provides plenty of wiggle room such that compliant implementations can be different enough that they produce different results from the same sequence of mathematical operations. You can probably see where this is going, right? Turns out that Arm and x86 don't always produce bit-exact results.

Since Apple wanted to guarantee very high levels of emulation fidelity, they provided another CPU mode bit which makes the FPU behave exactly like a x86 SSE FPU.


Note that Docker Desktop for Mac has always used a VM to run a Linux instance. Same with Docker Desktop on Windows (I don't know if this has changed with WSL). The main difference on M1 Macs is the qemu emulation when a Docker image is only available as x86_64. If the image is available in AArch64 it runs native on the M1.


WSL1 doesn't support cgroups and other pieces needed to run containers, but Docker Desktop can use WSL2, which uses a lightweight VM in the background, so you are correct.


Oh yeah, I thought the whole VM thing was implied with the fact that Docker is a Linux technology...


> Same with Docker Desktop on Windows (I don't know if this has changed with WSL).

Not really. On Windows you can choose if you want to run Linux binaries in a VM or native Windows containers.


Native Windows Containers run Native Windows Binaries. You can't just launch your Linux docker containers using Native Windows Containers.


I feel Windows Containers are a whole separate thing. I personally have never seen anyone use them, but then again I have never worked on a Windows Server stack.


Thank you for the thorough explanation.

Why can’t Rosetta 2 do the x86-to-ARM JIT translation inside the “Docker for Mac” VM instead of using the (presumably slower) QEMU emulation?

Or is QEMU smart enough to do the same translation that Rosetta 2 does which, if I recall correctly, only loses about 25% performance compared to native x86?


Rosetta 2 is Apple's product that is specifically geared towards translating Darwin binaries. Inside the VM is standard Linux. Linux can't run Rosetta 2 since that is a macOS tool.

QEMU emulates a platform on the fly, it does not attempt to rewrite the code to run on ARM and cache that result. QEMU also emulates all the specific quirks of the x86_64 platform, whereas Rosetta 2 does not.

It would be neat if Apple open sourced their Rosetta 2 technology and made it more widely available, but at this time there is no option for 3rd parties to use Rosetta 2, especially from within a Linux VM.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: