NDK 支持 ARM 高级 SIMD,通常称为 Neon,这是 ARMv7 和 ARMv8 的可选指令集扩展。Neon 提供与 x86 世界中的 MMX/SSE/3DNow! 相当的标量/向量指令和寄存器(与 FPU 共享)。
所有基于 ARMv8(“arm64”)的 Android 设备都支持 Neon。几乎所有基于 ARMv7(“32 位”)的 Android 设备都支持 Neon,包括所有搭载 API 级别 21 或更高版本的设备。NDK 为两者默认启用 Neon。
如果您面向非常旧的设备,可以在 Google Play Console 上过滤掉不兼容的设备。您还可以使用控制台查看您的应用会影响多少设备。
或者,为了最大程度地兼容,32 位代码可以执行运行时检测以确认 Neon 代码可以在目标设备上运行。应用可以使用CPU 功能中提到的任何选项执行此检查。
您可以在 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=OFF"
}
}
}
}
按模块禁用 Neon
ndk-build
要构建 ndk-build 模块中所有不使用 Neon 的源文件,请将以下内容添加到 Android.mk 中的模块定义中
LOCAL_ARM_NEON := false
CMake
要构建 CMake 目标中所有不使用 Neon 的源文件,请将以下内容添加到 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 - 自动移植解决方案、技巧和窍门。
示例代码
hello-neon 示例提供了一个如何同时使用cpufeatures
库和 Neon 内联函数的示例。此示例为 FIR 滤波器循环实现了一个小型基准测试,其中包含 C 版本和针对支持 Neon 的设备的 Neon 优化版本。