Android NDK开发详解之架构和 CPU中的Neon 支持

使用原生代码时,硬件很重要。NDK 提供各种 ABI 供您选择,可让您确保针对正确的架构和 CPU 进行编译。

本部分介绍了在构建时如何面向特定的架构和 CPU,如何使用 ARM Neon 扩展指令集,以及在运行时如何使用 CPU 功能库查询可选功能。

NDK 支持 ARM 高级 SIMD(通常称为 Neon),一种适用于 ARMv7 和 ARMv8 的可选扩展指令集。Neon 提供标量/矢量指令和寄存器(与 FPU 共享),与 x86 中的 MMX/SSE/3DNow! 类似。

几乎所有基于 ARMv7 的 Android 设备都支持 Neon,包括搭载 API 级别 21 或更高级别的所有设备。NDK 默认启用 Neon。

所有基于 ARMv8 的 Android 设备都支持 Neon。

NDK 支持模块编译,甚至可以编译支持 Neon 的特定源文件。您可以在 C 和 C++ 代码中使用 Neon 内建函数来充分利用高级 SIMD 扩展指令集。针对 Armv8-A 的 Neon 程序员指南详细介绍了 Neon 内建函数和 Neon 编程的概况。

构建

注意:对于 NDK r21 及更高版本,默认情况下,系统会为所有 API 级别启用 Neon。如果您需要停用 Neon 以支持非 Neon 设备(很少见),请用相反的值完成下述设置。另外,对于不支持 Neon 的 CPU,可使用 Play 商店管理中心来排除相应 CPU,以防您的应用安装到这些设备上。

全局启用 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=ON"
            }
        }
    }
}

为每个模块启用 Neon

ndk-build
要使用 NEON 在 ndk-build 模块中构建所有源文件,请将以下内容添加到 Android.mk 的模块定义中:

LOCAL_ARM_NEON := true

CMake

要使用 NEON 在 CMake 目标中构建所有源文件,请将以下内容添加到 CMakeLists.txt 中:


if(ANDROID_ABI STREQUAL armeabi-v7a)
    set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS -mfpu=neon)
endif()

其中 ${TARGET} 替换为您的库名称。

如果您要构建仅包含 Neon 代码的静态库或共享库,那么构建支持 Neon 的所有源文件将十分有用。

为每个源文件启用 Neon

ndk-build
为 LOCAL_SRC_FILES 变量列出源文件时,可以选择使用 .neon 后缀表示要构建支持 Neon 的单个文件。例如,以下示例会构建一个支持 Neon 的文件 (foo.c),以及另一个不支持 Neon 的文件 (bar.c):

LOCAL_SRC_FILES := foo.c.neon bar.c

您可结合使用 .neon 后缀与 .arm 后缀,后者指定用于非 Neon 指令的 32 位 ARM 指令集(而非 Thumb2)。在这种情况下,.arm 必须在 .neon 之前。例如:foo.c.arm.neon 可行,但 foo.c.neon.arm 不可行。
CMake

要使用 Neon 构建特定的源文件,请将以下内容添加到 CMakeLists.txt 中:

if(ANDROID_ABI STREQUAL armeabi-v7a)
    set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -mfpu=neon)
endif()

运行时检测

几乎所有基于 ARMv7 的 Android 设备都支持 Neon,包括搭载 API 级别 21 或更高级别的所有设备。NDK 默认启用 Neon。为实现最大兼容性,32 位代码可执行运行时检测,以确认 Neon 代码能够在目标设备上运行。应用可以使用 CPU 功能中提及的任一选项执行此检查。

另外,您也可以在 Google Play 管理中心中过滤掉不兼容的设备。还可以使用管理中心查看这会影响到多少设备。

对 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 优化的基准。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五一编程

程序之路有我与你同行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值