为多种体系结构生成优化的NDK代码?
我有一些用于Android的C代码,可以处理大量的低级别数字。 我想知道我应该使用什么设置(例如,我的Android.mk和Application.mk)文件,以便生成的代码可以在所有当前Android设备上运行,但也可以利用特定芯片组的优化。 我正在寻找良好的默认Android.mk和Application.mk设置来使用,并且我想避免使用#ifdef分支乱丢我的C代码。
例如,我知道ARMv7具有浮点指令,一些ARMv7芯片支持NEON指令,默认的ARM不支持这两种指令。 是否可以设置标志,以便我可以用NEON构buildARMv7,没有NEON的ARMv7和默认的ARM构build? 我知道如何做后两个,但不是全部3.我对使用什么设置谨慎,因为我认为当前的默认设置是最安全的设置,其他选项有什么风险。
对于GCC特定的优化,我使用以下标志:
LOCAL_CFLAGS=-ffast-math -O3 -funroll-loops
我已经检查了所有这三个加速我的代码。 还有其他常见的我可以添加吗?
我的另一个build议是在Android.mk上添加“LOCAL_ARM_MODE:= arm”,以加快新的arm芯片的速度(尽pipe我很困惑这是什么以及旧芯片会发生什么)。
ARM处理器有两个通用的指令集:“ARM”和“Thumb”。 虽然两者有不同的风格,但是ARM指令是32位,而Thumb指令是16位。 两者之间的主要区别在于,ARM指令有可能在Thumb指令的单个指令中执行更多操作。 例如,单个ARM指令可以将一个寄存器添加到另一个寄存器,而在第二个寄存器上执行左移。 在拇指一个指令将不得不做转变,然后第二个指令将做这个加法。
ARM指令不是两倍,但在某些情况下,它们可以更快。 在手动assembly的ARMassembly中,尤其如此,可以通过新颖的方式进行调整,以最大限度地利用“免费换class”。 拇指指示有其自身的优势,以及大小:他们耗尽电池less。
无论如何,这就是LOCAL_ARM_MODE所做的 – 这意味着您将代码编译为ARM指令而不是Thumb指令。 编译为Thumb是NDK中的默认设置,因为它倾向于创build一个较小的二进制文件,速度差异对于大多数代码来说并不明显。 编译器不能总是利用ARM可以提供的额外“优势”,所以最终你需要或多或less的相同数量的指令。
从编译到ARM或Thumb的C / C ++代码中看到的结果将是相同的(禁止编译器错误 )。
这本身就是适用于今天所有Android手机的新旧ARM处理器之间的兼容。 这是因为默认情况下,NDK编译为支持ARMv5TE指令集的基于ARM的CPU的“应用程序二进制接口”。 这个ABI被称为“armeabi”,可以通过将APP_ABI := armeabi
明确地设置在Application.mk中。
较新的处理器还支持被称为armeabi-v7a
的Android专用ABI,它扩展了armeabi以添加Thumb-2指令集和一个名为VFPv3-D16的硬件浮点指令集。 armeabi-v7a兼容CPU还可以select支持NEON指令集,在运行时您必须检查它,并提供代码path,以便何时可用以及何时不可用。 NDK / samples目录中有一个例子(hello-neon)。 在引擎盖下,Thumb-2更像“ARM”,因为它的指令可以在单个指令中做更多的事情,同时占用更less空间的优势。
为了编译包含armeabi和armeabi-v7a库的“fat binary”,你可以在Application.mk中添加以下内容:
APP_ABI := armeabi armeabi-v7a
安装.apk文件时,Android包pipe理器会为设备安装最佳的库。 所以在较旧的平台上,它将安装armeabi库,并在较新的设备上安装armeabi-v7a。
如果要在运行时testingCPUfunction,则可以使用NDK函数uint64_t android_getCpuFeatures()
获取处理器支持的function。 这将返回v7a处理器上的ANDROID_CPU_ARM_FEATURE_ARMv7
位标志,如果支持硬件浮点,则返回ANDROID_CPU_ARM_FEATURE_VFPv3
如果支持高级SIMD指令,则返回ANDROID_CPU_ARM_FEATURE_NEON
。 没有VFPv3,ARM不能有NEON。
总之:默认情况下,你的程序是最兼容的。 由于使用ARM指令,使用LOCAL_ARM_MODE可能会以牺牲电池寿命为代价,使速度稍快一些,并且与默认设置兼容。 通过添加APP_ABI := armeabi armeabi-v7a
行,您将在新设备上提高性能,保持与较旧设备兼容,但.apk文件将更大(由于有2个库)。 为了使用NEON指令,您需要编写特殊的代码来在运行时检测CPU的function,这只适用于运行armeabi-v7a的新设备。
很好的答案,就像添加你应该使用
APP_ABI := all
这将编译4个二进制文件,armv5,armv7,x86和mips
你可能需要一个新版本的ndk