Enter your email address to follow our blog with all the latest software engineering tricks, tips, and updates from the R&D team at KnowBe4!
By: Vignesh Hari
Published: 5 Jul 2023
Last Updated: 5 Jul 2023
You might be wondering why do CPU architectures matter and why are there different ones. You can think of them like car engines, they are all designed to perform the same function, some are designed with efficiency and low emissions in mind, some designed to be smaller, some made for performance etc. Different CPU architectures evolved to solve different problems.
Most of the CPUs in use now are based on either x86/64 or ARM.
With more computers being released with ARM based CPUs and major players like Apple turning to ARM based machines, the demand for ARM compatibility has gone up. The simplest way to run incompatible architecture is to emulate it. Apple solved its transition from Intel based machines to its own chips using Rosetta, although it was great for some software, most struggled for performance.
Docker is one of the tools developers use the most, most docker users did not face issues when moving from x86 to ARM based images because docker emulated the architecture the image was created in, seems perfect but the emulation was buggy, inconsistent and had poor performance. To show the exact performance difference let's take an example of a python application running in docker.
We'll consider a simple python application that finds the digits of pi(leibniz formula)
import sys def leibniz(n): t_sum = 0 for i in range(n): term = (-1) ** i /(2*i+1) t_sum = t_sum + term return t_sum * 4 print(leibniz(int(sys.argv)))
We'll also create a docker image that runs this python program
FROM python:latest WORKDIR /opt/app COPY . . # entrypoint just runs the python script // python3 pythoncode.py 10000000 ENTRYPOINT ["/opt/app/entrypoint.sh"]
Running the image in native and emulated mode (To get the emulated image, the image can be built on an x86 machine), we get the following results:
|Image Type||Avg Runtime|
The native image outperformed the emulation by around 10x. Now that we know that native images perform better, let's look at some methods on building images that can run on multiple architectures.
Docker supports multiple platforms ( architectures ) in a single image tag. Most of docker's official images support multiple architectures. By default, building an image builds it in the host's architecture. For production pipelines, we can create different machines that build different versions of an image with the same tag and then push it to a central repository.
To create images in different architectures on the same machine, we can specify the platform in which the image is to be built on in the docker build command. To build an image in the x86 architecture, we can use the following command
docker build . -t <tag> --platform linux/amd64
Even if you are running in an ARM based machine, you can build the application in the X86 architecture with this command.
Testing docker images on different platforms helps to understand how a build performs in various platforms and ensure its stability. This would allow devs working on multiple platforms to collaborate together. Automated tests that run on docker can utilise this feature and run tests on multiple platforms with little to no code change.
Major Cloud providers like AWS are heavily investing in custom-built ARM chips with lower cost and higher throughput/efficiency, applications that can run on these platforms can utilise them and get upto 20% better price performance. AWS lambda instances on ARM are around 20% cheaper than its x86 alternatives with around 34% better price performance.
KnowBe4 Engineering heavily uses On-Demand environments for quick iterations on native cloud-based…
How KnowBe4 solved the "It Works on My Machine" problem with a new approach to provisioning test…