The announcement of Graviton2 support for AWS Lambda, which boasts “up to 19 percent better performance at 20 percent lower cost”1 compared to its x86-based predecessor, has left many of us wondering “great, so what’s the catch?”
For the vast majority of developers, there is no catch—almost everything should “just work.” In this brief post though, we will walk you through a few possible issues you could encounter and how to deal with them.
A typical use-case for Lambda is running a relatively simple procedure written in a high-level programming language, with perhaps a few external packages installed, that finishes its execution in milliseconds. Everything within the standard library of a high-level programming language, such as Python, should work out of the box. Additionally, nearly all commonly used packages within these ecosystems have already been ported to arm architectures.
The only circumstances in which you, as a developer, might (emphasis on the might) run into an issue with Graviton-based Lambda include floating point comparisons and converting floats, with relation to these operations being performed within portions of imported packages that make calls to native C/C++ code.
The first potential issue, floating point comparisons, should be of little consequence. In short, float values determined within one architecture may slightly differ with the values determined by another. Mathematically speaking, the two values might be equivalent to one another, but when comparing them programmatically, i.e. float_from_x86 == float_from_arm, you may get “false” as a result. Again, for most use cases this limitation is completely irrelevant, but if you are putting incredibly precise workloads on Lambda, it might be a good idea to review which numerical datatypes you are using and ensure appropriate levels of rounding are occurring.
The second issue, in regards to converting floats, pertains to undefined C behavior:
In the event that you are casting a negative float to an unsigned int, you will likely arrive at different values across architectures. However, developers can audit their code to find out where this is happening:
The first image displays an example of casting a float as an unsigned int, on an x86-based platform. The second image displays that, when compiling with the -fsanitize flag, the compiler will notify you that you are entering dangerous territory. However, with this flag omitted, -2.7 becomes 4294967294.
In contrast, when running this same code (with an additional printf to make the “0” more obvious in the picture) on an arm-based EC2 instance, we can observe that the resulting value is 0, not 4294967294.
I hope that this short article helps to clarify that, for developers, using ARM-based Lambda should be an easy transition with only minor pitfalls that should not affect most of us. In the event that your Lambda function is experiencing float-related problems, the two “gotchas” mentioned above may be the cause of your trouble.