Dealing with CPU features

ABI: using the preprocessor's pre-defined macros

It's usually most convenient to determine the ABI at build time using #ifdef in conjunction with:

  • __arm__ for 32-bit ARM
  • __aarch64__ for 64-bit ARM
  • __i386__ for 32-bit X86
  • __x86_64__ for 64-bit X86

Note that 32-bit X86 is called __i386__, not __x86__ as you might expect!

CPU core counts: using libc's sysconf(3)

sysconf(3) lets you query both _SC_NPROCESSORS_CONF (the number of CPU cores in the system) and _SC_NPROCESSORS_ONLN (the number of CPU cores currently online).

Features: using libc's getauxval(3)

In API level 18 and newer, getauxval(3) is available in Android's C library. The AT_HWCAP and AT_HWCAP2 arguments return bitmasks listing CPU-specific features. See the various hwcap.h headers in the NDK for the constants to compare against, such as HWCAP_SHA512 for arm64's SHA512 instructions, or HWCAP_IDIVT for arm's Thumb integer division instructions.

The Google cpu_features library

One problem with AT_HWCAP is that sometimes devices are mistaken. Some old devices, for example, claim to have integer division instructions but do not.

Google's cpu_features library works around such issues by applying its own knowledge of specific SoCs (by parsing /proc/cpuinfo to work out the specific SoC in question).

This library is maintained for use by Google's first-party app teams, and has workarounds for every problematic device they've encountered in the wild.

The NDK cpufeatures library (deprecated)

The NDK still provides a deprecated library named cpufeatures for source compatibility with apps that already use it. Unlike the newer and more complete cpu_features library, this historical library does not have workarounds for about specific SoCs.