NDK 支持 ARM Advanced SIMD,通常称为 Neon,它是 ARMv7 和 ARMv8 的可选指令集扩展。Neon 提供标量/向量指令和寄存器(与 FPU 共享),可与 x86 世界中的 MMX/SSE/3DNow! 相媲美。
所有基于 ARMv8(“arm64”)的 Android 设备都支持 Neon。几乎所有基于 ARMv7(“32 位”)的 Android 设备都支持 Neon,包括所有随 API 级别 21 或更高版本发布的设备。NDK 默认同时为这两种架构启用 Neon。
如果您定位非常旧的设备,可以在 Google Play 管理中心过滤掉不兼容的设备。您也可以通过应用的控制台查看这将影响多少设备。
另外,为了最大程度兼容,32 位代码可以执行运行时检测,以确认 Neon 代码可在目标设备上运行。应用可以使用CPU 功能中提到的任何选项执行此检查。
您可以在 C 和 C++ 代码中使用 Neon intrinsic 函数来利用 Advanced SIMD 扩展。适用于 Armv8-A 的 Neon 程序员指南提供了有关 Neon intrinsic 函数和 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) intrinsic 函数跨平台编译为 x86 SSE 代码。如需详细了解此主题,请参阅 从 ARM NEON 到 Intel SSE - 自动移植解决方案、技巧和窍门。
示例代码
hello-neon 示例提供了如何同时使用 cpufeatures
库和 Neon intrinsic 函数的示例。此示例实现了 FIR 滤波器循环的一个小型基准测试,其中包含 C 版本和适用于支持 Neon 的设备的 Neon 优化版本。