NDK 支援 ARM 進階 SIMD (通常稱為 Neon),這是一種適用於 ARMv7 和 ARMv8 的可選指令集擴充功能。Neon 提供純量/向量指令和暫存器 (與 FPU 共用),與 x86 中的 MMX/SSE/3DNow! 類似。
幾乎所有 ARMv7 型 Android 裝置都支援 Neon,包括搭載 API 級別 21 以上版本的所有裝置。NDK 預設會啟用 Neon。
所有 ARMv8 型 Android 裝置都支援 Neon。
NDK 支援模組編譯,甚至可以編譯支援 Neon 的特定來源檔案。您可以在 C 和 C++ 程式碼中使用 Neon 內建函式,就能充分運用進階 SIMD 擴充功能。針對 Armv8-A 的 Neon 程式設計師指南中詳細介紹 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=ON"
}
}
}
}
為每個模組啟用 Neon
ndk-build
如要使用 NEON 在 ndk-build 模組中建構所有來源檔案,請將以下內容新增至 Android.mk 的模組定義中:
LOCAL_ARM_NEON := true
CMake
如要使用 NEON 在 CMake 目標中建構所有來源檔案,請將以下內容新增至 CMakeLists.txt 中:
if(ANDROID_ABI STREQUAL armeabi-v7a)
set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS -mfpu=neon)
endif()
其中,${TARGET}
會替換為您的程式庫名稱。
如果您想要建構只包含 Neon 程式碼的靜態程式庫或共享程式庫,則建構支援 Neon 的所有來源檔案將十分有用。
為每個來源檔案啟用 Neon
ndk-build
為 LOCAL_SRC_FILES
變數列出來源檔案時,您可以選擇使用 .neon
後置字串,藉此表示要建構支援 Neon 的個別檔案。例如,以下範例會建構一個支援 Neon 的檔案 (foo.c
),以及另一個不支援 Neon 的檔案 (bar.c
):
LOCAL_SRC_FILES := foo.c.neon bar.c
您可以將 .neon
後置字串和 .arm
後置字串搭配使用,後者指定用於非 Neon 指令的 32 位元 ARM 指令集 (而不是 Thumb2)。
在這種情況下,.arm
必須位於 .neon
之前。例如:foo.c.arm.neon
可行,但 foo.c.neon.arm
不可行。
CMake
如要使用 Neon 建構特定來源檔案,請將以下內容新增至 CMakeLists.txt 中:
if(ANDROID_ABI STREQUAL armeabi-v7a)
set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -mfpu=neon)
endif()
執行階段偵測
幾乎所有 ARMv7 型 Android 裝置都支援 Neon,包括搭載 API 級別 21 以上版本的所有裝置。NDK 預設會啟用 Neon。 為提高相容性,32 位元程式碼可以透過執行階段偵測功能,確認 Neon 程式碼可在目標裝置上執行。應用程式可以使用「CPU 功能」一文中提及的任一選項執行這項檢查。
另外,您可以在 Google Play 管理中心篩選出不相容的裝置,還可以透過管理中心查看受影響的裝置數量。
為 x86 提供跨平台支援
NDK 支援透過第三方 NEON_2_SSE.h 將現有 ARM SIMD (Neon) 內建函式跨平台編譯到 x86 SSE 程式碼中。如要進一步瞭解這個主題,請參閱從 ARM NEON 到 Intel SSE:自動移植解決方案、提示與秘訣。
程式碼範例
hello-neon 範例提供了例子,說明如何同時使用 cpufeatures
程式庫與 Neon 內建函式。這個範例實作了 C 版本的微小 FIR 篩選器迴圈基準,並針對支援 Neon 的裝置實作了 Neon 最佳化版本的基準。