APP_ABI: CPU architectures

1、armeabi 

This is the default option, which should be compatible with all ARM devices. Thumb is a special instruction set that encodes instructions on 16 bits instead of 32 to improve code size (useful for devices with constrained memory). The instruction set is severely restricted compared to ArmEABI. 

2、armeabi with LOCAL_ARM_CODE = arm 

(Or Arm v5) Should run on all ARM devices. Instructions are encoded on 32 bits but may be more concise than Thumb code. Arm v5 does not support advanced extensions such as floating point acceleration and is thus slower than Arm v7. 

3、armeabi-v7a 

Supports extensions such as Thumb-2 (similar to Thumb but with additional 32-bit instructions) and VFP, plus some optional extensions such as NEON. Code compiled for Arm V7 will not run on Arm V5 processors. 

4、armeabi-v7a-hard 

This ABI is an extension of the armeabi-v7a that supports hardware floats instead of soft floats. 

5、arm64-v8a 

This is dedicated to the new 64-bit processor architecture. 64-bit ARM processors are backward compatible with older ABIs. 

6、x86 and x86_64 

For "PC-like" processor architectures (that is, Intel/AMD). These are the ABIs used on the emulator in order to get hardware acceleration on a PC. Although most Android devices are ARM, some of them are now X86-based. The x86 ABI is for 32-bit processors and x86_64 is for 64-bit processors. 

7、mips and mips 64 

For processors made by MIPS Technologies, now property of Imagination Technologies well-known for the PowerVR graphics processors. Almost no device uses these at the time of writing this book. The mips ABI is for 32-bit processors and mips64 is for 64-bit processors. 

8、all, all32 and all64 

This is a shortcut to build an ndk library for all 32-bit or 64-bit ABIs. 

To achieve code performance, ARM created a SIMD instruction set (acronym Single Instruction Multiple Data, that is, process several data in parallel with one instruction) called NEON, which has been introduced along with the VFP (floating point accelerated) unit. NEON is not available on all chips (for example, Nvidia Tegra 2 does not support it), but is quite popular in intensive multimedia applications. They are also a good way to compensate the weak VFP unit of some processors (for example, Cortex-A8).

A NEON code can be written in a separate assembler  file in a dedicated asm volatile block with assembler instructions, or in a C/C++  file or as intrinsics (NEON instructions encapsulated in a GCC C routine). Intrinsics should be used with much care as GCC is often unable to generate efficient machine code (or requires lots of tricky hints). Writting real assembler code is generally advised.

X86 CPUs have their own set of extensions that are different from the ARM ones: MMX, SSE, SSE2, and SSE3. SSE instruction sets are the Intel equivalent of NEON SIMS instructions. The latest SSE4 instructions are generally not supported on current X86 processors. Obviously, SSE and NEON are not compatible, which means that a code specifically written for NEON needs to be rewritten for SSE and reciprocally.

NEON, SSE, and modern processors in general are not easy to master. The Internet is full of examples to get inspiration from. Reference technical documenta on can be found on the ARM website at http://infocenter.arm.com/ and the Intel developer manuals at http://www.intel.com/.

MIPS also has its own SIMD instruction set named MSA. It provides features such as vector arithmetics and branching operations, or conversion between integer and  floating-point values. For more information, have a look at http://www.imgtec.com/mips/architectures/simd.asp.

All this stuff  is interesting but it does not answer the question you are probably asking yourself: how hard it is to port code from ARM to X86 (or reciprocally)? The answer is "it depends":

1. If you use pure C/C++ native code, without specific instruction set, code should be portable simply by appending x86 or mips to the APP_ABI variable.
‹2. If your code contains assembly code, you will need to rewrite the corresponding part for other ABI or provide a fallback.
3. If your code contains specific instruction sets such as NEON (using C/C++ intrinsics or assembly code), you will need to rewrite corresponding part for other ABIs or provide a fallback.
‹4. If your code depends on specific memory alignment, you might need to use explicit alignment. Indeed, when you compile a data structure, the compiler might use padding to align data in memory appropriately for faster memory accesses. However, alignment requirements are different depending on the ABI. For example, 64-bit variables on ARM are aligned to 8, which means that double must have a memory address, which is a multiple of 8. X86 memory can be more densely packed.

So, most of the time, porting code from one ABI to another should be rather simple. In specific cases, provide fallbacks when specific CPU features or assembly code is necessary. Finally, beware, some memory alignment issues might arise in some rare cases.

posted @ 2016-03-22 11:16  壬子木  阅读(362)  评论(2)    收藏  举报