Home | History | Annotate | Download | only in text
      1 Android NDK x86 (a.k.a. IA-32) instruction set support
      2 ===
      3 
      4 Introduction:
      5 -------------
      6 
      7 Android NDK r6 added support for the '`x86`' ABI, that allows native code to
      8 run on Android-based devices running on CPUs supporting the IA-32 instruction
      9 set.
     10 
     11 The Android x86 ABI itself is fully specified in docs/CPU-ARCH-ABIS.html.
     12 
     13 Overview:
     14 ---------
     15 
     16 Generating x86 machine code is simple: just add 'x86' to your APP_ABI
     17 definition in your Application.mk file, for example:
     18 
     19         APP_ABI := armeabi armeabi-v7a x86
     20 
     21 Alternatively, since NDK r7, you can use:
     22 
     23         APP_ABI := all
     24 
     25 will generate machine code for all supported ABIs with this NDK. Doing so
     26 will ensure that your application package contains libraries for all target
     27 ABIs. Note that this has an impact on package size, since each ABI will
     28 correspond to its own set of native libraries built from the same sources.
     29 
     30 The default ABI is still '`armeabi`', if unspecified in your project.
     31 
     32 As you would expect, generated libraries will go into `$PROJECT/libs/x86/`, and
     33 will be embedded into your .apk under `/lib/x86/`.
     34 
     35 And just like other ABIs, the Android package manager will extract these
     36 libraries on a *compatible* x86-based device automatically at install time,
     37 to put them under <dataPath>/lib, where <dataPath> is the
     38 application's private data directory.
     39 
     40 Similarly, the Google Play server is capable of filtering applications
     41 based on the native libraries they embed and your device's target CPU.
     42 
     43 Debugging with ndk-gdb should work exactly as described under docs/NDK-GDB.html.
     44 
     45 ARM NEON intrinsics support:
     46 ----------------------------
     47 
     48 The solution is shaped as C/C++ language header with the same name as standard
     49 arm neon intrinsics header "arm_neon.h" which is also available in all NDK x86
     50 toolchains. It translates neon intrinsics to native x86 SSE ones.
     51 
     52 By default SSE up to SSE3 is used for porting ARM NEON to Intel SSE.
     53 
     54 Current solution covers by default ~41% NEON functions (889 of total 1884) and
     55 47% when -mssse3 is enabled. It is highly recommended to use the -mssse3 compiler
     56 flag for more coverage and performance.
     57 
     58 If currently provided coverage is not enough to port application please look
     59 into next version preview (up to 98% NEON instrinsics covered) at
     60 
     61 > http://software.intel.com/en-us/blogs/2012/12/12/from-arm-neon-to-intel-mmxsse-automatic-porting-solution-tips-and-tricks
     62 
     63 The solution
     64 
     65   - Redefines ARM NEON 128 bit vectors as the corresponding x86 SIMD data.
     66 
     67   - Redefines some functions from ARM NEON to Intel SSE if 1:1 correspondence
     68     exists.
     69 
     70   - Implements some ARM NEON functions using Intel SIMD if the performance
     71     effective implementation is possible.
     72 
     73   - Implements some of the remaining NEON functions using the serial solution
     74     and issuing the corresponding "low performance" compiler warning.
     75 
     76 ### Performance:
     77 
     78 For the major number of cases it is expected to obtain the similar to ARM NEON
     79 native perfomance gain for vectorized vs. serial code.
     80 
     81 ### Porting considerations and best known methods are:
     82 
     83   - Use 16-byte data alignment for faster load and store
     84 
     85   - Avoid NEON functions working with constants. It produces performance
     86     penalty for constants load\propagation.
     87     If constants usage is necessary try to move constants initialization out of
     88     hotspot loops and if applicable replace it with logical and compare
     89     operations.
     90 
     91   - Try to avoid functions marked as "serialy implemented" because they need to
     92     store data from registers to memory, process them serialy and load them again.
     93     Probably you could change the data type or algorithm used to make the whole
     94     port vectorized not a serial one.
     95 
     96 To learn more about it, see
     97 
     98 > http://software.intel.com/en-us/blogs/2012/12/12/from-arm-neon-to-intel-mmxsse-automatic-porting-solution-tips-and-tricks
     99 
    100 ### Sample code:
    101 
    102 In your project add 'x86' to APP_ABI definition and make sure "arm_neon.h"
    103 header is included.
    104 Your code will be ported to x86 without any other changes necessary.
    105 
    106 
    107 Standalone-toolchain:
    108 ---------------------
    109 
    110 It is possible to use the x86 toolchain with NDK r6 in stand-alone mode.
    111 See docs/STANDALONE-TOOLCHAIN.html for more details. Briefly speaking,
    112 it is now possible to run:
    113 
    114       $NDK/build/tools/make-standalone-toolchain.sh --arch=x86 --install-dir=<path>
    115 
    116 The toolchain binaries have the `i686-linux-android- prefix`.
    117 
    118 
    119 Compatibility:
    120 --------------
    121 
    122 The minimal native API level provided by official Android x86 platform builds
    123 is 9, which corresponds to all the native APIs provided by Android 2.3, i.e.
    124 Gingerbread (note also that no new native APIs were introduced by Honeycomb).
    125 
    126 You won't have to change anything to your project files if you target an older
    127 API level: the NDK build script will automatically select the right set of
    128 native platform headers/libraries for you.
    129