Neon 支持

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