psihodelia
psihodelia

Reputation: 30512

Runtime CPU type detection for Android on ARM

What is the simplest method to determine CPU type from within a running C application? I am interested in determining how many cores current CPU has and whether it has a NEON unit. One simple solution could be to check cpuinfo flags in /proc but I am not sure if it's a fast and reliable method.

Upvotes: 3

Views: 4697

Answers (4)

jww
jww

Reputation: 102376

Since you have the NDK tag here's a C context answer. When using modern NDKs I believe you are expected to use Android's cpu-features library.

Copy cpu-features.h and cpu-features.c from $ANDROID_NDK_ROOT/sources/android/cpufeatures to your project source tree. Compile it as part of your sources.

Then...


... determine CPU type from within a running C application?

To test whether the CPU is ARMv7 perform the following. The Android docs state to test the family first with android_getCpuFamily().

bool IsARMv7()
{
#if defined(__ANDROID__) && (defined(__aarch64__) || defined(__arm__))
    if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
        ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_ARMv7) != 0))
            return true;
#endif
    return false;
}

... how many cores current CPU has and whether it has a NEON unit

To test for NEON use the following code. NEON is called ASIMD on ARMv8/Aarch64.

bool HasNEON()
{
#if defined(__ANDROID__) && defined(__aarch64__)
    if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
        ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_ASIMD) != 0))
            return true;
#elif defined(__ANDROID__) && defined(__arm__)
    if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
        ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0))
            return true;
#endif
     return false;
}

According to the cpu-features library docs you use the following for CPU core count. I have never used it, though.

int  android_getCpuCount(void);

Upvotes: -1

landerlyoung
landerlyoung

Reputation: 1810

You can use the Build.SUPPORTED_ABIS to check CPU Abi version(eg,arm64-v8a, armeabi-v7a, etc.).

And also, to check is neon supported, using the /proc/cpuinfo file.

ABI

Sample Code

@SuppressWarnings("deprecation")
public static List<String> getSupportedABIs() {
    if (Build.VERSION.SDK_INT >= 21) {
        return Arrays.asList(Build.SUPPORTED_ABIS);
    } else {
        return Arrays.asList(Build.CPU_ABI, Build.CPU_ABI2);
    }
}

sample out put is:

|    device     |   arch     |         Abi list
| Moto Nexus 6  | arm 32bit  | [armeabi-v7a, armeabi]
| Huawei Mate 8 | arm 64bit  | [arm64-v8a, armeabi-v7a, armeabi]
| OPPO R7s      | arm 64 bit | [arm64-v8a, armeabi-v7a, armeabi]
| Moto X Style  | arm 64 bit | [arm64-v8a, armeabi-v7a, armeabi]

NEON

Here is a sample output of 'cat /proc/cpuinfo'

shell@mako:/ $ cat /proc/cpuinfo
Processor   : ARMv7 Processor rev 2 (v7l)
processor   : 0
BogoMIPS    : 13.53

processor   : 1
BogoMIPS    : 13.53

processor   : 2
BogoMIPS    : 13.53

processor   : 3
BogoMIPS    : 13.53

Features    : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt
CPU implementer : 0x51
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0x06f
CPU revision    : 2

Hardware    : QCT APQ8064 MAKO
Revision    : 000b
Serial      : 0000000000000000

Take care about the Features line. It contains all features the CPU supported. Note: the neon feature is listed.

So the very easy way to check if current device support neon, you just create a InputStreamReader("/proc/cpuinfo"), and read the Features line.

BTW

Those method described above try to avoid using native lib. If you want more detailed info about the cpu, try the official NDK library cpufeatures. And there is a ndk-sample.

Upvotes: 1

Marat Dukhan
Marat Dukhan

Reputation: 12273

You could use Yeppp! library to get a lot of information about CPU. This information is also accessible via Java bindings, so you could define several native methods in your classes, e.g. processGeneric() and processNeon(), and call the NEON method only if the CPU supports it:

import info.yeppp.Library;
import info.yeppp.ArmCpuSimdFeature;
import info.yeppp.CpuMicroarchitecture;

if (Library.isSupported(ArmCpuSimdFeature.NEON)) {
    if (Library.getMicroarchitecture().equals(CpuMicroarchitecture.Krait)) {
        /* Special NEON implementation for recent Qualcomm processors */
        nativeClass.processKrait();
    } else {
        /* Generic NEON implementation */
        nativeClass.processNeon();
    }
} else {
    /* Generic implementation without NEON */
    nativeClass.processGeneric();
}

Upvotes: 1

Leonidos
Leonidos

Reputation: 10518

You can check neon support using this doc. To get core count read this thread and take a look at this page.

Upvotes: 3

Related Questions