cpufeatures ライブラリ

NDK には、cpufeatures という小さなライブラリが含まれています。アプリでこのライブラリを実行時に使用すると、対象端末の CPU ファミリーとサポートするオプション機能を検出することができます。 このライブラリはそのままの状態ですべての公式 Android プラットフォーム バージョンで機能するように設計されています。

使用方法

cpufeatures ライブラリはインポート モジュールとして使用できます。このライブラリを利用する手順は次のとおりです。

  1. 静的ライブラリの依存関係のリストに cpufeatures を追加します。次に例を示します。
    LOCAL_STATIC_LIBRARIES := cpufeatures
    
  2. ソースコードに <cpu-features.h> ヘッダー ファイルを含めます。
  3. android/cpufeatures モジュールをインポートするための命令を Android.mk ファイルの最後に挿入します。 次に例を示します。
    $(call import-module,android/cpufeatures)
    

    cpufeatures ライブラリをインポートする Android.mk ファイルの簡単な例を次にしまします。

    <project-path>/jni/Android.mk:
    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := <your-module-name>
    LOCAL_SRC_FILES := <your-source-files>
    LOCAL_STATIC_LIBRARIES := cpufeatures
    include $(BUILD_SHARED_LIBRARY)
    
    $(call import-module,android/cpufeatures)
    

関数

cpufeatures ライブラリは 2 つの関数を提供します。最初の関数は、端末の CPU が属しているファミリーを返します。 この関数を次のように宣言します。

AndroidCpuFamily android_getCpuFamily();

この関数は、端末がサポートする CPU ファミリー / アーキテクチャを表す次のいずれかの列挙型を返します。

  • ANDROID_CPU_FAMILY_ARM
  • ANDROID_CPU_FAMILY_X86
  • ANDROID_CPU_FAMILY_MIPS
  • ANDROID_CPU_FAMILY_ARM64
  • ANDROID_CPU_FAMILY_X86_64
  • ANDROID_CPU_FAMILY_MIPS64

64 ビットシステムの 32 ビット実行ファイルの場合、この関数は 32 ビット値のみを返します。

2 番目の関数は、端末の CPU がサポートするオプション機能のセットを返します。この関数を次のように宣言します。

uint64_t android_getCpuFeatures();

戻り値の形式はビットフラグのセットであり、各フラグは 1 つの CPU ファミリー固有の機能を表してしています。 このセクションの残りでは、各ファミリーの機能について説明します。

32 ビット ARM CPU ファミリー

32 ビット ARM CPU ファミリーでは、次のフラグが使用できます。

ANDROID_CPU_ARM_FEATURE_VFPv2
端末の CPU では、VFPv2 命令セットがサポートされることを示します。ほとんどの ARMv6 CPU はこの命令セットをサポートします。
ANDROID_CPU_ARM_FEATURE_ARMv7
端末の CPU では、armeabi-v7a ABI の場合と同じように、ARMv7-A 命令セットがサポートされることを示します。 この命令セットは、Thumb-2 命令と VFPv3-D16 命令の両方をサポートします。 この戻り値は、VFPv3 ハードウェア FPU 命令セットの拡張機能がサポートされることも示します。
ANDROID_CPU_ARM_FEATURE_VFPv3
端末の CPU では、VFPv3 ハードウェア FPU 命令セットの拡張機能がサポートされることを示します。

この値は VFPv3-D16 命令セットと同等であり、16 ビット ハードウェア倍精度 FP レジスタのみを提供します。

ANDROID_CPU_ARM_FEATURE_VFP_D32
端末の CPU では、16 ビットレジスタではなく、32 ビット ハードウェア倍精度 FP レジスタがサポートされることを示します。 32 ビット ハードウェア倍精度 FP レジスタがあっても、32 ビット単精度レジスタのみが同じレジスタバンクにマッピングされます。
ANDROID_CPU_ARM_FEATURE_NEON
端末の CPU では、ARM Advanced SIMD(NEON)ベクター命令セットの拡張機能がサポートされることを示します。 ARM では、このような CPU で VFPv3-D32 も実装することが必須であることに注意してください。VFPv3-D32 は 32 ビット ハードウェア FP レジスタ(NEON ユニットと共有される)を提供します。
ANDROID_CPU_ARM_FEATURE_VFP_FP16
端末の CPU では、16 ビットレジスタで浮動小数点演算を実行するための命令がサポートされることを示します。 この機能は VFPv4 仕様の一部です。
ANDROID_CPU_ARM_FEATURE_VFP_FMA
端末の CPU では、VFP 命令セットの Fused Multiply ACcumulate 拡張機能がサポートされることを示します。 この機能は VFPv4 仕様の一部です。
ANDROID_CPU_ARM_FEATURE_NEON_FMA
端末の CPU では、NEON 命令セットの Fused Multiply ACcumulate 拡張機能がサポートされることを示します。 この機能は VFPv4 仕様の一部です。
ANDROID_CPU_ARM_FEATURE_IDIV_ARM
端末の CPU では、ARM モードの整数除算がサポートされることを示します。Cortex-A15 などの新型 CPU のみで使用できます。
ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2
端末の CPU では、Thumb-2 モードの整数除算がサポートされることを示します。Cortex-A15 などの新型 CPU のみで使用できます。
ANDROID_CPU_ARM_FEATURE_iWMMXt
端末の CPU では、MMX レジスタおよび命令を追加する命令セットの拡張機能がサポートされることを示します。 この機能は、少数の XScale ベースの CPU のみで使用できます。
ANDROID_CPU_ARM_FEATURE_LDREX_STREX
端末の CPU では、ARMv6 以降で使用できる LDREX および STREX 命令がサポートされることを示します。これらの命令により、排他的モニタを活用してメモリ上のアトミック アップデートが実行されます。

64 ビット ARM CPU ファミリー

64 ビット ARM CPU ファミリーでは、次のフラグが使用できます。

ANDROID_CPU_ARM64_FEATURE_FP
端末の CPU には、浮動小数点演算ユニット(FPU)があることを示します。すべての Android ARM64 端末はこの機能をサポートする必要があります。
ANDROID_CPU_ARM64_FEATURE_ASIMD
端末の CPU には、Advanced SIMD(ASIMD)ユニットがあることを示します。すべての Android ARM64 端末はこの機能をサポートする必要があります。
ANDROID_CPU_ARM64_FEATURE_AES
端末の CPU では、AES 命令がサポートされることを示します。
ANDROID_CPU_ARM64_FEATURE_CRC32
端末の CPU では、CRC32 命令がサポートされることを示します。
ANDROID_CPU_ARM64_FEATURE_SHA1
端末の CPU では、SHA1 命令がサポートされることを示します。
ANDROID_CPU_ARM64_FEATURE_SHA2
端末の CPU では、SHA2 命令がサポートされることを示します。
ANDROID_CPU_ARM64_FEATURE_PMULL
端末の CPU では、64 ビット PMULL および PMULL2 命令がサポートされることを示します。

32 ビット x86 CPU ファミリー

32 ビット x86 CPU ファミリーでは、次のフラグが使用できます。

ANDROID_CPU_X86_FEATURE_SSSE3
端末の CPU では、SSSE3 命令の拡張機能セットがサポートされることを示します。
ANDROID_CPU_X86_FEATURE_POPCNT
端末の CPU では、POPCNT 命令がサポートされることを示します。
ANDROID_CPU_X86_FEATURE_MOVBE
端末の CPU では、MOVBE 命令がサポートされることを示します。この命令は、Atom などの一部の Intel IA-32 CPU に固有のものです。

android_getCpuFeatures() は、拡張機能がリストされていない CPU ファミリーに対して 0 を返します。

次の関数は、対象端末の CPU コアの最大数を返します。

int  android_getCpuCount(void);

MIPS CPU ファミリー

ANDROID_CPU_MIPS_FEATURE_R6
CPU では、MIPS Release 6 命令がネイティブに実行され、カーネル トラップのみを介して古い形式の R1..R5 命令がサポートされることを示します。
ANDROID_CPU_MIPS_FEATURE_MSA
CPU では、MIPS SIMD Architecture 命令がサポートされることを示します。

変更履歴

このライブラリの完全な変更履歴については、$NDK/sources/android/cpufeatures/cpu-features.c にあるコメントをご覧ください。ここで、$NDK は NDK インストールのルートです。