Virtualisation on Apple silicon Macs: 1 How well does it work?

Virtualisation may not seem something to get excited about, but it has become sufficiently simple and versatile on Apple silicon Macs to have hit the headlines. This article asks how well it works in practice.

In this context, virtualisation lets you run a different operating system for the same processor architecture, not one for a different processor architecture. Thus, on an Apple silicon host computer you can run guest operating systems including Universal versions of macOS and Linux built for ARM, but not macOS or Linux for Intel hardware. Apple has recently blurred this a little by allowing ARM Linux guests to take advantage of Rosetta 2 translation to run Intel apps for Linux in an ARM Linux guest, but you can’t virtualise any Intel operating system as a guest on an Apple silicon host.

macOS offers two levels of virtualisation support: Hypervisor is a lower level used more commonly by commercial virtualisation software such as Parallels. To implement a full environment at that level requires a lot of code to support accelerated graphics, storage, network and other devices, and is a major undertaking. Virtualization offers a higher level, where most key services are already available, and merely have to be configured and integrated into a simple virtualiser app. As a result, indie developers are already offering free apps using Apple’s Virtualization features. My own basic test app is a mere 200 KB in size.

The big question over this lightweight, simple virtualisation is whether it can perform as well as a commercial alternative.

To perform these assessments, I built Viable, my own lightweight virtualiser app in Swift, based on Apple’s example code, which provides an excellent start. I did this using the current beta-release of Xcode 14 running on the current beta of Ventura, although all results reported here are from my app running in Monterey 12.4 on my Mac Studio Max.

lightweightvm1

CPU and GPU

Because virtualisation doesn’t involve emulating the CPU of a different architecture, code which runs on processor cores should be essentially unaltered, and should therefore perform identically on the host and from within the guest. Measured using in-core benchmarks using my app AsmAttic, this is true for lightweight virtualisation:

  • integer test 3.8 s on the host, 3.9 s in the guest;
  • floating-point test 6.4 s host, 6.4 s guest;
  • NEON test 1.1 s host, 1.1 s guest;
  • Accelerate test 1.1 s host, 1.1 s guest;
  • mixed test 149 s host, 149 s guest.

You must bear in mind, though, that the performance of any virtualiser is limited by the number of cores that you devote to it. For those tests, I configured my guest to have four cores, and ran only two threads in each test. Guests are inevitably more likely to run out of free cores than their hosts (when not running a VM).

I’ve been unable to benchmark accelerated graphics and GPU performance because the only test I have is embedded in an App Store app, which can’t be run on the lightweight virtualiser, as I’ll explain below. However, Apple claims host Metal performance from within the guest, and I have no reason to doubt that.

Storage

There are two options for storage in macOS guests: a VIRTIO Block Device, which is required for the boot volume group, including the Data volume, and a VIRTIO file system device, which can be used for shared storage with the host, but isn’t fully available in Monterey. For this assessment, I’ll confine myself to the Block Device, which has to be used for standard storage.

The Block Device is implemented in a disk image, which immediately raises questions as to its performance. The 2 TB internal SSD in my Mac Studio Max performs well: tested using Stibium or any of the popular disk benchmarking apps, its read speed is 8.1 GB/s for random files between 2 MB and 2 GB, and it writes at 7.3 GB/s. Create an unencrypted APFS Disk Image of 100 GB and read speed drops a little to 7.8 GB/s while write speed collapses to 1.3 GB/s. The latter is also more variable, ranging between 0.7-6.7 GB/s.

As Apple’s Virtual I/O (VIRTIO) interface adds its own overhead, performance with the Block Device is even worse than a Disk Image. When reading from the virtual Data volume, speed was 4.4 GB/s, and write speed was 0.7 GB/s, ranging between 0.4-4.5 GB/s.

The current implementation of VIRTIO Block Device storage needs improvement, although as long as it remains based on the Disk Image, it’s always going to write far slower than the host can. It will be interesting to see whether VIRTIO file system devices perform any better.

I also haven’t been able to get VIRTIO shared storage working yet, which is a serious limitation to the use of my app. For example, the most convenient way to copy apps and other files to and from it is by connecting over the network to another Mac with file sharing enabled. That’s probably just my own inability, though.

Networking

There are also two options for network devices: a Bridged Network Device sends and receives packets over the same physical interface as the host, delivering best performance, while a NAT Network Device routes through NAT in the host. However, the first of those is only available when Apple has granted a provision to use the com.apple.vm.networking entitlement, so isn’t likely to appear in many implementations of lightweight virtualisation.

In addition to being slower, a NAT Network Device has the major disadvantage that it appears unable to support logging into your Apple ID or iCloud account. That has major impact on what you can do in a lightweight virtual machine, and is entirely within Apple’s control.

Other devices

Lightweight virtual machines enjoy good support for most other devices, including keyboard and pointing devices and displays. Other devices which I’ve not yet assessed include audio, memory (a ‘balloon’ to change allocated memory for the guest), random number generation, serial ports, sockets, consoles, and sharing of clipboards.

Conclusions
Lightweight virtual machines using Virtualization of macOS on Apple Silicon:

  • deliver similar CPU and (probably) GPU/Metal performance as the host;
  • write to Block Device storage at around 10% of the speed of the host, and read at just over 50%;
  • can’t log into Apple ID or iCloud services without a restricted entitlement;
  • provide excellent but limited virtualisation.

I will look in more detail at these and other issues in future articles. If my own app Viable ever gets its rough edges smoothed off I’ll be releasing it when it’s ready. In the meantime, if you want to try out lightweight virtualisation on Apple silicon, I recommend Guilherme Rambo’s VirtualBuddy.