Adding x86 target to your Android App allows developers to compile their native code libraries for x86 platforms in addition to ARM. This expands an app's reach to devices with Intel processors. Most NDK apps will run on x86 without recompilation by setting the APP_ABI flag in Application.mk to "all" or "x86". For code using SIMD or processor-specific instructions, modifications may be needed along with compiler optimizations like vectorization for best performance on x86. Debugging tools like Valgrind, GDB and logcat work to debug native code issues on both ARM and x86 Android platforms.
Handwritten Text Recognition for manuscripts and early printed texts
Adding x86 target support to your Android App
1. Adding x86 target to your Android App
Xavier Hallade, Technical Marketing Engineer, Intel
2. What we are working on for Android*
Key AOSP and
Kernel Contributor
Porting and
Optimizing
Browser and Apps
Optimized Drivers
& Firmware
NDK Apps Bridging
Technology
Highly Tuned
Dalvik Runtime
64
bit
64-Bit
3. Our devices are already fully compatible with
established Android* ecosystem
Android* Dalvik* apps
These will directly work, Dalvik has been
optimized for Intel® platforms.
Android Runtime
Dalvik Virtual
Machine
Core Libraries
Android NDK apps
Most will run without any recompilation on consumer platforms.
Android NDK provides an x86 toolchain since 2011
A simple recompile using the Android NDK yields the best performance
If there is specific processor dependent code, porting may be necessary
Most of the time, it just works !
4. What’s a NDK app ?
It’s an Android* application that uses native libraries.
Native libraries are .so files, usually found inside
libs/CPU_ABI/.
An application can use some calls to these
native libraries, or rely almost exclusively on
these.
These libs can be generated from native sources
inside jni folder, game engines, or required by
other 3rd party libraries.
There is no 100% native application. Even an
application purely written in C/C++, using
native_app_glue.h, will be executed in the
context of the Dalvik Virtual Machine.
6. Smartphones with Intel Inside - 2012
Z2460
Orange* San Diego (UK)
Orange* avec Intel Inside (FR)
Lava* Xolo X900
Motorola* RAZR i
ZTE* Grand X IN
Megafon* Mint
Lenovo*
K800
7. Smartphones with Intel Inside - 2013
Z2420
Z2560
Z2580
Lenovo* K900 – 5.5”
Intel® Yolo
ASUS Fonepad™ Note FHD - 6”
Etisalat E-20*
ZTE* Geek – 5”
Acer* Liquid C1
…
ZTE* Grand X2 In – 4.5”
8. Tablets with Intel Inside - 2013
ASUS* MeMO Pad FHD 10”
ASUS* Fonepad™ 7”
(Z2560)
(Z2420/Z2560)
Samsung* Galaxy™ Tab 3 10.1”
(Z2560)
LTE version now available
Dell* Venue 7/8
(Z2560)
9. Future Android* platforms based on Intel*
Silvermont microarchitecture
New 22nm tri-gate microarchitecture
~3X more peak performance or ~5X lower power than previous Atom microarchitecture
Intel® Atom™ Processor Z3000 Series
(Bay Trail)
Next Generation Tablets
Merrifield
Next Generation Smartphones
10. How to target multiple platforms (incl. x86)
from NDK apps ?
11. Configuring NDK Target ABIs
If you have the source code of your native libraries, you can compile it for several CPU
architectures by setting APP_ABI to all in the Makefile “jni/Application.mk”:
APP_ABI=all
Put APP_ABI=all inside
Application.mk
Run ndk-build…
ARM v7a libs are built
ARM v5 libs are built
x86 libs are built
mips libs are built
The NDK will generate optimized code for all target ABIs
You can also pass APP_ABI variable directly to ndk-build, and specify each ABI:
ndk-build APP_ABI=x86
12. Packaging APKs for Multiple CPU Architectures
Two options:
PIDs
PSI
TS
One package for all (“fat binary”)
Embed native libraries for each architecture in one APK
Easiest and preferred way to go
Multiple APKs
One APK per architecture
If you have good reasons to do so (i.e., your fat binary APK would be
larger than 50MB)
13. Fat Binaries
Recommended
By default, an APK contains libraries for every supported ABIs.
libs/armeabi
Use lib/armeabi libraries
libs/armeabi-v7a
libs/x86
…
APK file
Use lib/armeabi-v7a
libraries
Use lib/x86
libraries
The application will be filtered during installation (after download)
14. Multiple APKs
Google Play* supports multiple APKs for the same application.
What compatible APK will be chosen for a device entirely depends on the
android:VersionCode
Using this convention, the chosen APK will be the one that run best on the
device:
• If you have multiple APKs only for multiple ABIs, you can simply prefix
your current version code with a digit representing the ABI:
2310
6310
15. Uploading Multiple APKs to the store
Switch to Advanced mode before
uploading the second APK.
The interface almost doesn’t change.
But if you upload a new apk in
simple mode, it will overwrite the
former one.
You can get the same screen than on
the right. even if the new package
will not overwrite the previous one.
16. Uploading Multiple APKs to the store
Don’t forget to use different version codes for your different APKs.
18. 3rd party libraries x86 support
Game engines/libraries with x86 support:
•
Havok Anarchy SDK: android x86 target available
•
Unreal Engine 3: android x86 target available
•
Marmalade: android x86 target available
•
Cocos2Dx: set APP_ABI in Application.mk
•
FMOD: x86 lib already included, set ABIs in Application.mk
•
AppGameKit: x86 lib already included, set ABIs in Application.mk
•
libgdx: x86 lib now available in latest releases
•
…
No x86 support but works on consumer devices:
•
Corona
•
Unity
19. 3rd party libraries x86 support
3rd party projects don’t always provide pre-compiled x86 android .so
files.
You may compile/port it yourself, starting by adding x86 target to
APP_ABI in jni/Application.mk Makefile and running ndk-build.
If you run into troubles, usually it’s a matter of fixing the build
system, with the help of TARGET_ARCH_ABI var:
ifeq ($(TARGET_ARCH_ABI),x86)
…
else
…
endif
21. SIMD Instructions
NEON* instruction set on ARM* platforms
MMX™, Intel® SSE, SSE2, SSE3, SSSE3 on Intel® Atom™ processor based platforms
http://intel.ly/10JjuY4 - NEONvsSSE.h : wrap NEON functions and intrinsics to
SSE3 – 100% covered
//******* definition sample *****************
int8x8_t
vadd_s8(int8x8_t a, int8x8_t b); // VADD.I8 d0,d0,d0
#ifdef USE_MMX
#define vadd_s8 _mm_add_pi8
//MMX
#else
#define vadd_s8 _mm_add_epi8
#endif
//…
Supplemental Streaming SIMD Extensions (SSSE)
Intel® Streaming SIMD Extensions (Intel® SSE)
Optimization Notice
Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These
optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any
optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors.
Certain optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides
for more information regarding the specific instruction sets covered by this notice.
Notice revision #20110804
22. Memory Alignment
By default
struct TestStruct {
int mVar1;
long long mVar2;
int mVar3;
};
Easy fix
struct TestStruct {
int mVar1;
long long mVar2 __attribute__ ((aligned(8)));
int mVar3;
};
24. Vectorization
SIMD instructions up to SSSE3 available on current Intel® Atom™ processor based
platforms, Intel® SSE4.2 on the next one that uses Silvermont Microarchitecture
0
127
X4
X3
X2
X1
Y4
Y3
Y2
Y1
X4◦Y4
X3◦Y3
X2◦Y2
X1◦Y1
SSSE3, SSE4.2
Vector size: 128 bit
Data types:
• 8, 16, 32, 64 bit integer
• 32 and 64 bit float
VL: 2, 4, 8, 16
On ARM*, you can get vectorization through the ARM NEON* instructions
Two classic ways to use these instructions:
Compiler auto-vectorization
Compiler intrinsics
Supplemental Streaming SIMD Extensions (SSSE)
Intel® Streaming SIMD Extensions (Intel® SSE)
Optimization Notice
Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These
optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any
optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors. Certain
optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides for more
information regarding the specific instruction sets covered by this notice.
Notice revision #20110804
25. GCC Flags
ifeq ($(TARGET_ARCH_ABI),x86)
LOCAL_CFLAGS += -O3 -ffast-math -mtune=atom -mssse3 -mfpmath=sse
else
LOCAL_CFLAGS += ...
endif
To optimize for Intel Silvermont Microarchitecture (available starting with NDK r9
gcc-4.8 toolchain):
NDK_TOOLCHAIN_VERSION=4.8
LOCAL_CFLAGS += -O3 -ffast-math -mtune=slm -msse4.2 -mfpmath=sse
ffast-math influence round-off of fp arithmetic and so breaks strict IEEE
compliance
The other optimizations are totally safe
Add -ftree-vectorizer-verbose to get a vectorization report
Optimization Notice
Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These
optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any
optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors. Certain
optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides for more
information regarding the specific instruction sets covered by this notice.
Notice revision #20110804
27. Debugging with logcat
NDK provides log API in <android/log.h>:
int __android_log_print(int prio, const char *tag,
const char *fmt, ...)
Usually used through this sort of macro:
#define LOGI(...)
((void)__android_log_print(ANDROID_LOG_INFO, "APPTAG",
__VA_ARGS__))
Example:
LOGI("accelerometer: x=%f y=%f z=%f", x, y, z);
28. Debugging with logcat
To get more information on native code execution:
adb shell setprop debug.checkjni 1
(already enabled by default in the emulator)
And to get memory debug information (root only):
adb shell setprop libc.debug.malloc 1
-> leak detection
adb shell setprop libc.debug.malloc 10
-> overruns detection
adb shell start/stop -> reload environment
29. Debugging with GDB and Eclipse
Native support must be added to your project
Pass NDK_DEBUG=1 to the ndk-build command, from the project
properties:
NDK_DEBUG flag is supposed to be automatically set for a debug
build, but this is not currently the case.
30. Debugging with GDB and Eclipse*
When NDK_DEBUG=1 is specified, a “gdbserver” file is added to your
libraries
31. Debugging with GDB and Eclipse*
Debug your project as a native Android* application:
32. Debugging with GDB and Eclipse
From Eclipse “Debug” perspective, you can manipulate breakpoints and debug your project
Your application will run before the debugger is attached, hence breakpoints you set near
application launch will be ignored
33. Valgrind
The Valgrind tool suite provides a number of debugging and profiling tools that help you make your
programs faster and more correct.
Memcheck : It can detect many memory-related errors that are common in C and C++ programs and
that can lead to crashes and unpredictable behavior.
Setting up Valgrind
Download latest version on Valgrind from http://valgrind.org/downloads/
./configure
Make
Sudo make install
Steps above should install valgrind.
Compile your program with -g to include debugging information so that Memcheck's error messages
include exact line numbers.
gcc myprog.c
valgrind --leak-check=yes myprog arg1 arg2 ; Memcheck is the default tool. The --leak-check option
turns on the detailed memory leak detector. You can also invoke the leak check like this
Valgrind ./a.out
Use “–o” to optimize the program while compiling. Any other option slows down Valgrind to a
significant extent.
34. Interpreting Valgrind error messages
Example of output message from Valgrind Memcheck
==19182== Invalid write of size 4
==19182== at 0x804838F: f (example.c:6) ==19182== by 0x80483AB: main (example.c:11)
19182 : Process ID
“Invalid write..” is the error message
6 and 11 are line numbers
Add “--gen-suppressions=yes ” to suppress errors arising out of pre compiled libs
and other mem leak errors that you cannot make changes to.
Memcheck cannot detect every memory error your program has. For example, it
can't detect out-of-range reads or writes to arrays that are allocated statically
or on the stack. But it should detect many errors that could crash your program
Suggested reading : http://valgrind.org/docs/manual/manual.html
36. Valgrind on Android x86
Installing Valgrind
Download this package: https://my.syncplicity.com/share/7cse0vnb43auckm/valgrind-x86-androidemulator
Unzip and enter root of the unzipped package.
Install valgrind on the emulator using these commands:
adb push Inst /
adb shell chmod 777 /data/local/Inst
adb shell chmod 755 /data/local/Inst/bin/*
adb shell chmod 755 /data/local/Inst/lib/valgrind/*
Setting up a program to be run with Valgrind
adb shell setprop wrap.com.example.hellojni "logwrapper /data/local/Inst/bin/valgrind“ #Replace package
name with your package name
Next startups of your app will be wrapped by valgrind and you'll see the output inside logcat.
Please note
These binaries are compatible with Intel HAXM 4.0.3 x86 emulator, not the 4.3.
You can use any OS as host
To use valgrind on a real device, you need to recompile valgrind for it (you can read the .sh file inside the
zip to get the right cmd and adapt it) and you need to be root on it.
37. Tools for Android* apps developers
HAXM, TBB, GPA, XDK and others
Most of our tools are relevant even if you’re not targeting x86 platforms!
38. Faster Android* Emulation on Intel® Architecture
Based Host PC
Pre-built Intel® Atom™ Processor Images
Android* SDK manager has x86 emulation images
built-in
To emulate an Intel Atom processor based Android
phone, install the “Intel Atom x86 System Image”
available in the Android SDK Manager
Much Faster Emulation
Intel® Hardware Accelerated Execution Manager (Intel®
HAXM) for Mac and Windows uses Intel®
Virtualization Technology (Intel® VT) to accelerate
Android emulator
Intel VT is already supported in Linux* by qemu -kvm
Intel x86 Atom
System Image
Intel x86 Emulator
Accelerator
39. ARM and x86 Emulators running AnTuTu*
Benchmark
40. Intel® Threading Building Blocks (TBB)
Specify tasks instead of manipulating threads
Intel® Threading Building Blocks (Intel® TBB) maps your logical tasks onto
threads with full support for nested parallelism
Targets threading for scalable performance
Uses proven efficient parallel patterns
Uses work-stealing to support the load balance of unknown execution
time for tasks
Open source and licensed versions available on Linux*, Windows*, Mac OS
X*, Android*…
Open Source version available on: threadingbuildingblocks.org
Licensed version available on: software.intel.com/en-us/intel-tbb
41. Intel® TBB - Example
#include <tbb/parallel_reduce.h>
#include <tbb/blocked_range.h>
Lambda function with
Calculating aa one- Pi
Defining a reduction
Computes part of
Defining
range and initial value as
dimensional range
within the range r
over a range
function
parm
double getPi() {
const int num_steps = 10000000;
const double step = 1./num_steps;
double pi = tbb::parallel_reduce(
tbb::blocked_range<int>(0, num_steps), //Range
double(0), //Value
//function
[&](const tbb::blocked_range<int>& r, double current_sum ) ->
double {
for (size_t i=r.begin(); i!=r.end(); ++i) {
double x = (i+0.5)*step;
current_sum += 4.0/(1.0 + x*x);
}
return current_sum; // updated value of the accumulator
},
[]( double s1, double s2 ) { //Reduction
return s1+s2;
}
);
return pi*step;
}
42. Intel® Graphics Performance Analyzers
• Profiles performance and Power
• Real-time charts of CPU, GPU and
power metrics
• Conduct real-time experiments
with OpenGL-ES* (with state
overrides) to help narrow down
problems
• Triage system-level performance
with CPU, GPU and Power metrics
Available freely on intel.com/software/gpa
43. Intel® Graphics Performance Analyzers
1. Install APK, and
connect to Host
PC via adb
2. Run Intel® GPA System
Analyzer on
development machine
3. View Profile
44. Preparing an Application for Analysis
Non-analyzable applications does not have the proper permissions and need
to be modified.
To analyze an application from the Non-analyzable applications list, you
need to modify the application’s permissions:
• Open the AndroidManifest.xml file of your application:
•
Enable the Internet connection permission:
<uses-permission android:name="android.permission.INTERNET">
•
Enable the debuggable permission:
<application android:debuggable="true">
45. Other tools and libs for Android*
• Intel Beacon Mountain
• Intel IPP Preview
• Intel Compiler
• Intel XDK New
• Project Anarchy