Central processing units (CPUs) can be compared to the human brain in that their unique architecture allows them to solve mathematical equations in different ways. x86 is the dominant architecture used in cloud computing at the time of this writing; however, it is worth noting that this architecture is not efficient for every scenario, and its proprietary nature is causing an industry shift toward ARM.
ARM (Advanced RISC Machines) is a type of CPU architecture that powers most tablets and smartphones, as well as the fastest supercomputer in the world (supercomputer Fugaku). ARM’s low power consumption and high computational performance make it a worthy rival for x86 in cloud computing.
In this article, I will talk about a few popular ARM projects, the main difference between x86 and ARM architectures, and explore how we can prepare developers for the future by providing them with an ARM-based container environment.
ARM versus x86
Companies are increasing their pursuit to leverage ARM in order to reduce both cost and energy consumption. While x86 remains a proprietary CPU architecture, ARM provides licenses to other companies allowing them to design their own custom-built processors using ARM’s patented technology.
Amazon’s custom-designed Graviton processor is a great example of ARM in cloud computing. By using these processors, AWS A1 instances offer a comparable performance to x86 EC2 instances while saving 40% in costs.
The main difference between ARM and x86 can be traced back to the way these CPUs execute instructions. As an example, an ordinary x86 desktop CPU uses an implementation of complex instruction set computer (CISC) architecture, allowing for a single instruction to execute multi-step operations in each clock cycle.
ARM, on the other hand, uses an implementation of reduced instruction set computer (RISC) architecture, allowing it to utilize a limited, highly optimized set of instructions to execute a single instruction in each clock cycle.
Before I continue, let’s address the elephant in the room. You might be thinking, “Many container runtime environments, like Docker, can use the
buildx (or similar) command to create containers for a variety of CPU architectures—so why are we even having this conversation?”
docker build --platform can create a platform-specific image, you cannot run commands that execute binary files from your recipes (Dockerfiles).
In the following example, you can see a failed build due to the difference between the host and binary architecture type.
$ docker build --platform=linux/arm64 . Sending build context to Docker daemon 2.048kB Step 1/2 : FROM arm64v8/alpine:latest ---> bb3de5531c18 Step 2/2 : RUN apk update ---> [Warning] The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64) and no specific platform was requested ---> Running in 84d06aedf134 standard_init_linux.go:228: exec user process caused: exec format error The command '/bin/sh -c apk update' returned a non-zero code: 1
Containers share CPU and kernel with the host, which means the underlying hardware dictates which instruction set can be used in the container environment. This can be seen (highlighted in red) in the previous Docker build output.
Executable programs that we use are compiled as binary files. Compilation is a magical step in the software development process where a compiler (software) takes a piece of source code (arguably human readable!) and converts it into binary machine code (i.e. ones and zeros) that is specific to the CPU. In simple terms: programs are made by other programs! (There are interpreter-based languages that can directly execute instructions from the source code, but let’s not dive into that abyss.)
Linux to the rescue
Packed with features, the Linux kernel is a modular piece of software that can be extensively customized based on your usage requirements. One of these features (
binfmt_misc) allows you to run almost any binary files in your system by using an interpreter, regardless of the binary compiled architectures. Linux can be configured to use
binfmt_misc and match the beginning bytes of a binary file to identify which interpreter is suitable in order to execute it.
In our case, we need to run everything using an interpreter that can understand ARM64 CPU instructions. (binfmt and Linux kernel are huge topics and out of the scope of this article, but if you are interested, this article at kernal.org is a great place to start your journey.)
Project multiarch uses the same concept to register QEMU as an interpreter, allowing users to emulate various CPU architectures for containers.
Emulation is a great way to start testing and developing solutions without the need for actual hardware. However, it is worth noting that emulation adds a layer of overhead on top of the native platform, making it unsuitable for production environments.
Limited features and edge cases, such as lower performance output as a result of not being native, can be an example of emulation cost.
In recent years, programming languages have evolved to enable multi-architectural support, and in most cases there is little to no effort required to enable support for other architectures like ARM.
Web tier projects are a great starting point for ARM integration. As an example, projects like Apache and NGiNX are very popular web servers that already support the ARM architecture. It is worth noting that support for ARM is not the only benefit here, since running NGiNX as a caching server or a reverse proxy in an ARM environment will achieve better performance in comparison to x86.
In-memory databases are another area where ARM architecture can provide improvements. Utilizing RISC architecture, applications like Redis can achieve eye-catching performance in comparison to an x86 environment.
The following benchmarks are a comparison of Redis
get operations with both x86 and ARM64 CPU architectures.
A full range of use cases is a vast topic on its own and out of the scope of this post, but if you are interested, check out this AWS tech talk that shares some of its experiments and benchmarks for ARM64 architecture.
ARM architecture seems to be a great alternative to x86 systems; and because of its efficiency, companies are investing in its future for cloud computing. Transforming applications and clusters might enable cost savings without compromising on performance.
If you enjoyed this blog post, you might also like:
Join our mailing list
Get updates on blog posts, new releases and more!