----------------- 英文文檔見android-ndk-r5b的documentation.html 屬於Android Native Development Kit (NDK)的一部分
見http://developer.android.com/sdk/ndk/(需要代理) 翻譯僅個人見解
----------------- Android NDK & ARM NEON instruction set extension support
Android NDK 和 ARM NEON指令集擴充支援
-------------------------------------------------------- Introduction: 介紹:-------------
Android NDK r3 added support for the new 'armeabi-v7a' ARM-based ABI that allows native code to use two useful instruction set extensions:
Android NDK r3添加對新的基於ARM的armeabi-v7a ABI的支援,允許原生代碼使用兩個有用指令集擴充:
- Thumb-2, which provides performance comparable to 32-bit ARM instructions with similar compactness to Thumb-1 - Thumb-2,
它提供與32位ARM指令可比的效能,也提供與Thumb-1相似的緊湊性 - VFPv3,
which provides hardware FPU registers and computations, to boost floating point performance significantly. - VFPv3,
它提供硬體浮點處理單元寄存器和計算能力,顯著提升浮點效能。
More specifically, by default 'armeabi-v7a' only supports VFPv3-D16 which only uses/requires 16 hardware FPU 64-bit registers.
更顯著的是,預設armeabi-v7a只支援VFPv3-D16,VFPv3-D16隻使用/需要16個硬體浮點處理單元64位寄存器。
More information about this can be read in docs/CPU-ARCH-ABIS.html
更多相關資訊可以閱讀docs/CPU-ARCH-ABIS.html。
The ARMv7 Architecture Reference Manual also defines another optional instruction set extension known as "ARM Advanced SIMD", nick-named "NEON". It provides:
ARMv7架構參考手冊還定義另一個可選的指令集合,即ARM進階SIMD,暱稱為NEON。它提供:
- A set of interesting scalar/vector instructions and registers (the latter are mapped to the same chip area as the FPU ones), comparable to MMX/SSE/3DNow! in the x86 world.
- 一組有趣的標量/向量指令(註:標量指令是指處理器每次處理一條資料,而向量指令則相反,允許平行處理多條資料)和寄存器(後來被映射為相同的晶片領域如浮點運算單元寄存器),可以和x86世界的MMX/SSE/3DNow!相比。
- VFPv3-D32 as a requirement (i.e. 32 hardware FPU 64-bit registers, instead of the minimum of 16).
- VFPv3-D32作為一種最低需要(即32個硬體浮點單位64位寄存器,而非至少16個)。
Not all ARMv7-based Android devices will support NEON, but those that do may benefit in significant ways from the scalar/vector instructions.
不是所有基於ARMv7的Android裝置會支援NEON,而那些支援NEON的裝置可以從標向量指令中很有意義地獲得好處。
The NDK supports the compilation of modules or even specific source files with support for NEON. What this means is that a specific compiler flag will be used to enable the use of GCC ARM Neon intrinsics and VFPv3-D32 at the same time. The intrinsics are described here:
NDK支援模組的編譯或甚至是特定的原始碼,擁有對NEON的支援。這意味著將使用一個特定的編譯器開關同時開啟對GCC ARM Neon內建和VFPv3-D32的使用。內建功能在這裡描述:
http://gcc.gnu.org/onlinedocs/gcc/ARM-NEON-Intrinsics.html LOCAL_ARM_NEON: LOCAL_ARM_NEON
--------------- Define LOCAL_ARM_NEON to 'true' in your module definition, and the NDK will build all its source files with NEON support. This can be useful if you want to build a static or shared library that specifically contains NEON code paths.
在你的模組定義中把LOCAL_ARM_NEON定義為true,NDK則會用NEON支援構建所有源檔案。如果你想構建一個特定地包含NEON代碼路徑的靜態或動態庫,這可能有用。
Using the .neon suffix:
使用.neon尾碼:
----------------------- When listing sources files in your LOCAL_SRC_FILES variable, you now have the option of using the .neon suffix to indicate that you want to corresponding source(s) to be built with Neon support. For example:
當在你的LOCAL_SRC_FILES變數中列出源檔案時,你現在擁有使用.neon的選擇,以指出你想把原始碼相應地用Neon支援進行構建。例如:
LOCAL_SRC_FILES := foo.c.neon bar.c
Will only build 'foo.c' with NEON support. 將只對foo.c用NEON支援構建。
Note that the .neon suffix can be used with the .arm suffix too (used to specify the 32-bit ARM instruction set for non-NEON instructions), but must appear after it.
注意.neon尾碼可以同時使用.arm尾碼(用於指明對非NEON指令的32位ARM指令集),但必須出現在後面。
In other words, 'foo.c.arm.neon' works, but 'foo.c.neon.arm' does NOT.
換句話說,foo.c.arm.neon可以,但foo.c.neon.arm不可以。
Build Requirements:
構建需要:
------------------ Neon support only works when targetting the 'armeabi-v7a' ABI, otherwise the NDK build scripts will complain and abort. It is important to use checks like the following in your Android.mk:
Neon支援僅在目標是armeabi-v7a ABI時才可工作,否則NDK構建指令碼將解釋和中止。在你的Android.mk中使用類似如下方式的檢查是很重要的。
# define a static library containing our NEON code
# 定義一個靜態庫,包含我們的NEON代碼
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
include $(CLEAR_VARS)
LOCAL_MODULE := mylib-neon
LOCAL_SRC_FILES := mylib-neon.c
LOCAL_ARM_NEON := true
include $(BUILD_STATIC_LIBRARY)
endif #
TARGET_ARCH_ABI == armeabi-v7a
Runtime Detection:
運行時檢測:
------------------ As said previously, NOT ALL ARMv7-BASED ANDROID DEVICES WILL SUPPORT NEON ! It is thus crucial to perform runtime detection to know if the NEON-capable machine code can be run on the target device.
正如前面所說的,不是所有基於ARMv7的Android裝置支援NEON!因此最重要的是執行運行時檢測以知道NEON能力的機器代碼是否能運行在目標裝置上。
To do that, use the 'cpufeatures' library that comes with this NDK. To lean more about it, see docs/CPU-FEATURES.html.
為了做到那一點,可以使用NDK提供的cpufeatures庫。想知道更多相關資訊,請參考docs/CPU-FEATURES.html。
You should explicitly check that android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM, and that android_getCpuFeatures() returns a value that has the ANDROID_CPU_ARM_FEATURE_NEON flag set, as in:
你應該顯式地檢查android_getCpuFamily()返回ANDROID_CPU_FAMILY_ARM,並且android_getCpuFeatures()返回一個擁有ANDROID_CPU_ARM_FEATURE_NEON標記位設定的值,正如這樣:
#include
...
...
if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM && (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0)
{ // use NEON-optimized routines // 使用NEON最佳化常式 ...
} else { // use non-NEON fallback routines instead // 改為使用非NEON倒退常式
... } ...
Sample code:
範例程式碼:
------------ Look at the source code for the "hello-neon" sample in this NDK for an example on how to use the 'cpufeatures' library and Neon intrinsics at the same time.
查看這份NDK中hello-neon例子的原始碼以獲得關於如何同時使用cpufeatures庫和Neon內建的例子。
This implements a tiny benchmark for a FIR filter loop using a C version, and a NEON-optimized one for devices that support it.
它實現了一個使用C版本的FIR(註:有限脈衝響應)濾波器迴圈,以及針對支援硬體NEON的裝置的經過NEON最佳化的小型效能比較測試。