NEON サポート

NDK は、一般に NEON と呼ばれる ARM Advanced SIMD をサポートしています。NEON は、ARMv7 および ARMv8 向けのオプションの命令セット拡張です。NEON は、x86 環境の MMX / SSE / 3DNow! と同等のスカラー / ベクター命令とレジスタ(FPU と共有)を提供します。

ARMv8 ベース(「arm64」)の Android デバイスはすべて NEON をサポートしています。API レベル 21 以降を搭載したすべてのデバイスを含め、ARMv7 ベース(「32 ビット」)のほぼすべての Android デバイスが NEON をサポートしています。NDK は、両方の Arm ABI でデフォルトで NEON を有効にしています。

非常に古いデバイスをターゲットにしている場合は、Google Play Console で互換性のないデバイスを除外できます。アプリのコンソールを使用して、影響を受けるデバイスの数を確認することもできます。

または、最大限の互換性を確保するため、32 ビットコードはランタイム検出を実行して、対象デバイスで NEON コードを実行できることを確認できます。このチェックの実行には、CPU 機能で紹介されているどの方法でも使用できます。

C/C++ コードで明示的な Neon イントリンシックを記述しないでください。Clang のポータブル ベクトル型は、Neon 命令を自動的に使用します。Clang の Neon 組み込み関数は、実際には移植可能な型の移植不可能なラッパーにすぎません。そのため、Neon 組み込み関数を記述しても、移植可能な型を使用するよりもコードが高速になることはなく、移植性が低下するだけです。

ビルド

NEON をグローバルに無効にする

ndk-build

ndk-build では、NEON をグローバルに無効にすることはできません。ndk-build アプリ全体で NEON を無効にするには、アプリ内のすべてのモジュールにモジュールごとの手順を適用します。

CMake

CMake を呼び出すときに -DANDROID_ARM_NEON=ON を渡します。Android Studio / Gradle でビルドする場合は、build.gradle で以下のオプションを設定します。

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                arguments "-DANDROID_ARM_NEON=OFF"
            }
        }
    }
}

モジュールごとに NEON を無効にする

ndk-build

NEON を使用せずに ndk-build モジュール内のすべてのソースファイルをビルドするには、Android.mk のモジュール定義に以下の行を追加します。

LOCAL_ARM_NEON := false

CMake

NEON を使用せずに CMake ターゲット内のすべてのソースファイルをビルドするには、CMakeLists.txt に以下の行を追加します。

if(ANDROID_ABI STREQUAL armeabi-v7a)
    set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS -mfpu=vfpv3-d16)
endif()

ここで ${TARGET} はライブラリの名前に置き換えます。

x86 向けのクロスプラットフォーム サポート

NDK は、サードパーティの NEON_2_SSE.h を使用することで、既存の ARM SIMD(NEON)イントリンシック関数を x86 SSE コードにコンパイルするクロスプラットフォーム コンパイルをサポートしています。詳細については、ARM NEON から Intel SSE へ - 自動移植ソリューション、ヒントとコツをご覧ください。

サンプルコード

ベクトル化のサンプルでは、さまざまなベクトル化ツールを使用して行列乗算を実装する方法を示し、そのパフォーマンスを比較しています。