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 优化版本。