x86 Support
The NDK includes support for the x86
ABI, which allows native code to run on Android-based devices running on CPUs supporting the IA-32 instruction set.
-
英特尔32位元架构(英语:Intel Architecture, 32-bit,缩写为IA-32),常被称为i386、x86-32或是x86,由英特尔公司推出的指令集架构,至今英特尔最受欢迎的处理器仍然采用此架构。
Overview概述
To generate x86 machine code, add x86
to the APP_ABI
definition in your Application.mk
file. For example:
APP_ABI := armeabi armeabi-v7a x86For more information about defining the
APP_ABI
variable, see
Application.mk
.
The build system places generated libraries into $PROJECT/libs/x86/
, where $PROJECT
represents your project's root directory, and embeds嵌入 them in your APK under /lib/mips/
.
The Android package extract提取 these libraries when installing your APK on a compatible兼容 x86-based device, placing them under your app's private data directory.
In the Google Play store, the server filters applications so that a consumer sees only the native libraries that run on the CPU powering his or her device.
x86 Support for ARM NEON Intrinsics
Support for ARM NEON intrinsics is provided in the form of C/C++ language headers with the same name as the standard ARM NEON intrinsics header, arm_neon.h
. These headers are available for all NDK x86 toolchains. They translate NEON intrinsics to native x86 SSE ones.
Characteristics of this solution include the following:
- Default use of SSE through SSSE3 for porting ARM NEON to Intel SSE, covering ~93% (1869 of total 2009) of all NEON functions.
- Redefinition重新定义 of ARM NEON 128 bit vectors into the equivalent等价 x86 SIMD data.
- Redefinition of some functions from ARM NEON to Intel SSE if a 1:1 correspondence exists对应的存在.
- Implementation of some ARM NEON functions using Intel SIMD if it will yield产生 a performant执行 result.
- Implementation of some of the remaining剩余的 NEON functions using the serial solution, and issuing发行,分配 the corresponding对应的 "low performance" compiler warning.
Performance
In most cases, you should be able to attain完成 performance similar to what you would get from ARM NEON code. Recommendations(建议 建议书) for best results include:
- Use 16-byte data alignment对齐,队列 for faster load and store.
- Avoid避免 using constants常量 with NEON functions. Using constants results in a performance penalty性能损失 due to having to load constants. If you must use constants, try to initialize them outside of hotspot loops. If possible, replace them with logical and compare operations合乎逻辑的和比较操作.
- Try to avoid functions marked as "serially连续地 implemented" because they need to store data from registers to memory. Instead, process处理 them serially and reload them. You may be able to change the data type or algorithm算法 used to vectorize矢量化 the whole port instead of leaving it as a serial one.
For more information on this topic, see From ARM NEON to Intel SSE– the automatic porting solution, tips and tricks.
Known differences from ARM version
In the great majority of cases, x86 implementations produce the same results as ARM implementations for NEON. x86 implementations pass NEON tests nearly 100% of the time. Still, there are several corner角落拐角 cases in which an x86 implementation produces results different from its ARM counterpart副本. Known incompatibilities不兼容性 are as follows:
VRECPS/VRECPSQ
If one of the operands(运算对象 运算物体 操作数) is +/- infinity无穷大 and the second is +/- 0.0:- On ARM CPUs, these instructions return a result element equal to 2.0.
- x86 CPUs return
QNaN Indefinite
. For more information about the QNaN floating-point indefinite, see "4.2.2 Floating-Point Data Types" and "4.8.3.7 QNaN Floating-Point Indefinite," in the Intel® 64 and IA-32 Architectures Software Developer’s Manual.
VRSQRTS/VRSQRTSQ
If one of the operands运算对象 运算物体 操作数) is +/- infinity无穷大 and the second is +/- 0.0:- On ARM CPUs, these instructions return a result element equal to 1.5.
- x86 CPUs return
QNaN Indefinite
. For more information about the QNaN floating-point indefinite, see "4.2.2 Floating-Point Data Types" and "4.8.3.7 QNaN Floating-Point Indefinite," in the Intel® 64 and IA-32 Architectures Software Developer’s Manual.
VMAX/VMAXQ
If one of the operands is NaN, or both operands are +/- 0.0:- On ARM CPUs, floating-point maximum works as follows:
- max(+0.0, -0.0) = +0.0.
- If any input is a NaN, the corresponding result element is the default NaN.
- On x86 CPUs, floating-point maximum works as follows:
- If one of the source operands is NaN, then return the second source operand.
- If both source operands are equal to 0, then return the second source operand.
- On ARM CPUs, floating-point maximum works as follows:
VMIN/VMINQ
If one of the operands is NaN or both are +/- 0.0:- On ARM CPUs floating-point minimum works as follows:
- min(+0.0, -0.0) = -0.0.
- If any input is a NaN, the corresponding对应的 result element is the default NaN.
- On x86 CPUs floating-point minimum works as follows:
- If one of the source operands is NaN, than return the second source operand.
- If both source operands are equal to 0, than return the second source operand.
- On ARM CPUs floating-point minimum works as follows:
VRECPE/VRECPEQ
These instructions provide different levels of accuracy on ARM and x86 CPUs. For more information about these differences, see How do I use VRECPE/VRECPEQ for reciprocal estimate? on the ARM website, and Volume 2, p. 4-281 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual.VRSQRTE/VRSQRTEQ
- These instructions provide different levels of accuracy on ARM and x86 CPUs. For more information about these differences, see the RealView Compilation Tools Assembler Guide, and Volume 2, p. 4-325 of theIntel® 64 and IA-32 Architectures Software Developer’s Manual.
- If one of the operands is negative or -infinity then
- On ARM CPUs, these instructions by default return a (positive) NaN. For more information about this result, see the ARM Compiler toolchain Assembler Reference.
- On x86 CPUs, these instructions return a (negative) QNaN floating-point Indefinite. For more information about this result, see Volume 1, Appendix E, E.4.2.3, of the Intel® 64 and IA-32 Architectures Software Developer’s Manual.
Sample code
In your project make sure to include the arm_neon.h
header, and define include x86
in your definition ofAPP_ABI
. The build system then ports your code to x86.
For an example of how porting ARM NEON to x86 SSE works, see the hello-neon sample.
Standalone Toolchain
You can incorporate结合 the x86
ABI into your own toolchain. For more information, see Standalone Toolchain.
Compatibility
x86 support requires, at minimum, Android 2.3 (Android API level 9). If your project files target an older API level, but include x86 as a targeted platform, the NDK build script automatically selects the right set of native platform headers/libraries for you.