VMs on M1

I have upgraded my laptop. It’s been a while (Mid 2014) and I felt like the new MacBook Pro is finally a computer I can use a while. It’s got an SD card slot, an HDMI port, MagSafe and enough USB ports (even though they are all USB-C). What I’m missing is an easy way to connect my old displayport screen, but I’ll fix that by upgrading that as well (it’s ~10 years old).

The machine is great – the screen, the silence even when under load, the fingerprint reader, I love it all. I have not had any issues with the apps due to it being Apple Silicon. What I have noticed is that some smaller utility apps I used have disappeared since I last did a fresh install – developers moved on, decided to not support the new platform or the new APIs. I have mostly1 found replacements, even if some are paid apps.

Reasoning

On my previous laptop I had all development stuff running directly on the Mac. This was a problem every time I upgraded the OS as random things would die and fixing them took a lot of time. So this time around I want to pack all my development stuff inside a linux VM that would then hold either code directly or docker containers.

My initial idea was to set up an x86_64 virtual machine, so that I could have an environment as close to what I normally use in production, but installing it in UTM took forever, so I abandoned that idea for now.

Software

Step one was setting up some virtual machines to test how that would work.

I have previously used VirtualBox, but they have not yet decided to support the M1, so what I found and tested was:

  1. UTM,
  2. Parallels Desktop for M1 and
  3. VMWare Fusion for Apple Silicon.

So I went about installing Ubuntu in all three environments. My source image was Ubuntu 20.04.3 LTS, the machines set up as arm with 8GB of RAM and 4 cores. In the case of UTM, the system is set to QEMU 5.0 ARM VM (virt-5.0)2 with CPU set to cortex-a72 and Force Multicore checked.

Shared directory

After installing I looked at how I can share a directory from the host inside the VM:

  1. UTM

    I haven’t figured it out yet as it wanted me to install something on my Mac, so I gave up (for now).

  2. Parallels Desktop

    Default instructions are to reboot and then mount a CD from which you install the relevant tools. This went well and the directories were shared under /media/psf.

  3. VMWare Fusion

    VMWare requires you to install vmware tools on linux and you should get the mount automatically, but I didn’t, so I hade to add the line to /etc/fstab manually. Going with fstab is nice, as you can mount the share anywhere you like.

Performance

With that solved, I did a quick test of speed inside the VMs. Nothing comprehensive, just a quick feeler to see what kind of performance I can expect. To do that I ran the following python code, output mimicking that of the ping command:

import statistics
import timeit

l = []
for i in range(10):
	l.append(timeit.timeit("hashlib.pbkdf2_hmac('sha256', b'password', b'salt', 100000)", "import hashlib", number=100) / 100 * 1000)

print("min/avg/max/stddev = {:.3f}/{:.3f}/{:.3f}/{:.3f} us".format(
	min(l),
	statistics.mean(l),
	max(l),
	statistics.pstdev(l)
))

Times:

  1. UTM

    min/avg/max/stddev = 15.442/15.479/15.510/0.018 us (python 3.8.10)

  2. Parallels Desktop

    min/avg/max/stddev = 14.582/14.659/14.809/0.077 us (python 3.8.10)

  3. VMWare Fusion3

    min/avg/max/stddev = 14.596/14.632/14.713/0.031 us (python 3.8.10)

  4. Host

    min/avg/max/stddev = 23.598/24.297/25.038/0.553 us (python 3.8.9)

  5. MacBook Pro (Mid 2014)

    min/avg/max/stddev = 308.944/316.638/326.198/4.993 us (python 3.5.2)

    min/avg/max/stddev = 64.027/64.870/66.026/0.658 us (python 3.8.8)

I have no idea why the VMs are faster than the host – my guess is the VMs are running on performance cores, so python also gets a performance core, while python on the host runs on the efficiency core. Haven’t yet figured out how to confirm this though.

Update: I added times from my old laptop. Oddly python 3.5 was way slower, while there is no difference in times between 3.5 and 3.8 on arm (tested on Parallels).

Result

I think UTM could be great especially with its low price (free online, 9.99€ on the App Store), but everything is a bit finicky. If you can use one of the images provided and you don’t need to set up directory sharing, it’s surely a good option.

I don’t yet have a preference between Parallels and Fusion – Fusion has better folder sharing approach but kidnaps the cursor, which is quite annoying. At the moment Fusion is free (full price for Fusion 12 Player is 135.53€ while Pro is 180.98€ in the Europe store at the moment), while Parallels is already a paid product (99.99€ one time or 79.99€ per year, 99.99€ per year for Pro). As far as I have read, VMWare does not intend to support anything that is not Arm, while Parallels already has that support, which might make me go that way.

Next up

Next things I want to figure out:

  • does running an x86_64 VM makes any sense?
  • is it possible to mount a VM HDD without running the VM?
  • set up PyCharm to work with this setup

If you’re interested in anything else, let me know.

  1. Anybody know of a replacement for PresenterMate? ^
  2. For some reason I could not make the install work on a higher version (5.1, 6.x) ^
  3. I initially thought Fusion was much slower, but I likely screwed something up when measuring ^

One Response to “VMs on M1”

  1. Marko says:

    Nice to see you writing again. I am very interested in PyCharm integration as this is where all container approaches fail for me. The DX experience is just bad.

    On the other hand my setup using asdf is not without problems either and still occasionally fails for reasons I don’t fully understand. So I’m searching for a set up that would actually work.

Leave a Reply