为多种体系结构生成优化的NDK代码?

rbc*_*bcc 53 c java-native-interface android gcc android-ndk

我有一些Android的C代码,可以进行大量的低级数字运算.我想知道我应该使用哪些设置(例如我的Android.mk和Application.mk),以便生成的代码可以在所有当前的Android设备上运行,但也可以利用特定芯片组的优化.我正在寻找使用良好的默认Android.mk和Application.mk设置,我想避免使用#ifdef分支丢弃我的C代码.

例如,我知道ARMv7有浮点指令,一些ARMv7芯片支持NEON指令,默认ARM不支持这些指令.是否可以设置标志,以便我可以使用NEON,没有NEON的ARMv7和默认的ARM构建来构建ARMv7?我知道如何做后两者但不是全部3.我对我使用的设置持谨慎态度,因为我认为当前默认设置是最安全的设置以及其他选项有哪些风险.

对于GCC特定的优化,我使用以下标志:

LOCAL_CFLAGS=-ffast-math -O3 -funroll-loops
Run Code Online (Sandbox Code Playgroud)

我检查了所有这三个加速了我的代码.还有其他我可以添加的常见内容吗?

我的另一个提示是将"LOCAL_ARM_MODE:= arm"添加到Android.mk以加快更新的手臂芯片(尽管我对这件事以及旧芯片上发生的事情感到困惑).

ric*_*chq 112

ARM处理器有2个通用指令集,它们支持:"ARM"和"Thumb".虽然两者都有不同的风格,但ARM指令各为32位,Thumb指令为16位.两者之间的主要区别在于ARM指令可以在一条指令中完成比Thumb更多的操作.例如,单个ARM指令可以将一个寄存器添加到另一个寄存器,同时在第二个寄存器上执行左移.在Thumb中,一个指令必须执行移位,然后第二个指令将执行添加.

ARM指令不是两倍好,但在某些情况下它们可以更快.在手动ARM组件中尤其如此,它可以以新颖的方式进行调整,以充分利用"免费换档".拇指说明书有各自的优点和尺寸:它们可以减少电量消耗.

无论如何,这就是LOCAL_ARM_MODE的作用 - 它意味着您将代码编译为ARM指令而不是Thumb指令.编译为Thumb是NDK中的默认值,因为它倾向于创建较小的二进制文件,并且速度差异对于大多数代码而言并不明显.编译器不能总是利用ARM可以提供的额外"oomph",因此最终需要或多或少相同数量的指令.

您从编译为ARM或Thumb的C/C++代码中看到的结果将是相同的(除了编译器错误).

对于目前可用的所有Android手机,这本身就兼容了新旧ARM处理器.这是因为默认情况下,NDK编译为支持ARMv5TE指令集的基于ARM的CPU的"应用程序二进制接口".这个ABI被称为"armeabi",可以通过put在Application.mk中明确设置APP_ABI := armeabi.

较新的处理器还支持特定于Android的ABI armeabi-v7a,它扩展了armeabi以添加Thumb-2指令集和称为VFPv3-D16的硬件浮点指令集.armeabi-v7a兼容CPU还可以选择支持NEON指令集,您必须在运行时检查它,并提供可用时和不可用时的代码路径.在NDK/samples目录中有一个例子(hello-neon).在引擎盖下,Thumb-2更像"ARM-like",因为它的指令可以在单个指令中完成更多工作,同时具有仍占用更少空间的优势.

为了编译包含armeabi和armeabi-v7a库的"胖二进制文件",您可以将以下内容添加到Application.mk:

APP_ABI := armeabi armeabi-v7a
Run Code Online (Sandbox Code Playgroud)

安装.apk文件后,Android软件包管理器会为该设备安装最佳库.因此,在较旧的平台上,它将安装armeabi库,而在较新的设备上安装armeabi-v7a.

如果要在运行时测试CPU功能,则可以使用NDK功能uint64_t android_getCpuFeatures()获取处理器支持的功能.如果支持硬件浮点并且支持高级SIMD指令ANDROID_CPU_ARM_FEATURE_ARMv7,ANDROID_CPU_ARM_FEATURE_VFPv3则返回v7a处理器的位标志ANDROID_CPU_ARM_FEATURE_NEON.没有VFPv3,ARM不能拥有NEON.

总结:默认情况下,您的程序是最兼容的.使用LOCAL_ARM_MODE可能会因为使用ARM指令而使电池寿命稍微快一些 - 并且它与默认设置兼容.通过添加该APP_ABI := armeabi armeabi-v7a行,您将在较新的设备上提高性能,保持与旧设备兼容,但您的.apk文件将更大(由于有2个库).为了使用NEON指令,您需要编写在运行时检测CPU功能的特殊代码,这仅适用于可以运行armeabi-v7a的新设备.


use*_*819 23

很好的答案,就像添加你应该使用

APP_ABI := all
Run Code Online (Sandbox Code Playgroud)

这将编译4个二进制文件,armv5,armv7,x86和mips

你可能需要新版本的ndk

  • 这是自ndk7以来的支持 (4认同)