Boost Performance for Your Android Native Code

The Android NDK is a toolset that lets you embed components that make use of native code in your Android applications.

The Android NDK is a toolset that lets you embed components that make use of native code in your Android applications. The Android NDK Revision 6, launched in July 2011, added the possibility of generating machine code that runs on compatible x86-based Android devices (IA-32). Thus, since that version, you can optimize the performance-critical portions of your apps to take advantage of most of the advanced SIMD instruction sets found in Intel Atom CPUs that run Android.

If you have some experience writing Android native code for the ARMv7 architecture, you are probably aware of the ARM Advanced SIMD instruction set extension, known as NEON. Intel Atom CPUs provide support for SSSE3 (short for Supplemental Streaming SIMD Extensions 3) and its predecessors, such as SSE3, SSE2, SSE, and MMX. You can easily take advantage of the powerful SIMD instructions up to SSE3 in order to optimize your algorithms for the x86 architecture with the Android NDK. The latest version of Android NDK is Revision 7, launched in November 2011, and it provides a specific ABI (short for Application Binary Interface) that defines exactly how the application’s machine code is expected to interact with an x86 (IA-32) system at runtime.

The x86 ABI provided by Android NDK Revision 7 details the CPU instruction set that the machine code should use up to SSE3 for Intel Atom, and therefore, it excludes SSSE3. It is still possible to use SSSE3 but you have to use both runtime features probing to enable them and fallbacks for devices that don’t support the extended instruction set.

The SSE3 instruction set is different than NEON but you can easily port NEON to SSE3 and its predecessor x86 SIMD extensions. In addition, you can write native code that targets x86 from scratch and take advantage of all the SIMD extensions provided by modern Intel Atom CPUs.

One of the main differences with ARM is that you don’t need to check for any specific CPU feature in x86 in order to use the SIMD instructions. If the value returned from android_getCpuFamily() is ANDROID_CPU_FAMILY_X86, you will have the SSE3 instruction set extensions and its predecessors available, because you have an Intel Atom. With ARM CPUs, it is necessary to check for the specific availability of NEON. It isn’t necessary to check a specific value returned in android_getCpuFeatures for Intel Atom and you don’t need to call that function at all.

If you want to have the best performance for your native code but you target multiple platforms, you can create the most efficient code based on the value retrieved from android_getCpuFamily and then you’ll have to check android_getCpuFeatures for ARM. However, for Intel Atom CPUs, you can use most of the SIMD instructions you already master and boost performance of Android native code portions of applications. In addition, you can use all the tools provided by Intel to optimize your algorithms, test them in your Intel Atom netbooks in order to solve potential bottlenecks, and finally build them with the x86 ABI provided by the Android NDK. The computing continuum makes it easy for experienced x86 developers to take advantage of their existing knowledge of the x86 platform on different devices and operating systems without having to learn new instruction sets. Android runs on Intel Atom, and the chips that run Android have the same instruction sets you already use in either a netbook or a tablet.

Developers that have experience in optimizing pieces of code to execute instructions in multiple data with SIMD during the last years have a great opportunity to boost performance and extend battery life for Android applications that require native code optimizations. You can read more information about Android on Intel Architecture in the Android Developers portal @ Intel Software Network.