Neon 支持

NDK 支持 ARM 高级 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 内建函数来充分利用高级 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

如需在不使用 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 代码中。要详细了解此内容,请参阅 From ARM NEON to Intel SSE-the automatic porting solution, tips and tricks(从 ARM NEON 到 Intel SSE:自动移植解决方案、提示与技巧)。

示例代码

hello-neon 示例举例说明了如何同时使用 cpufeatures 库和 Neon 内建函数。此示例实现了 C 版本的微小 FIR 过滤器循环基准,并针对支持 Neon 的设备实现了经 Neon 优化的基准。