[android codefest germany] adding x86 target to your android app by xavier hallade

45
Adding x86 target to your Android App Xavier Hallade, Technical Marketing Engineer, Intel

Post on 20-Oct-2014

1.558 views

Category:

Technology


3 download

DESCRIPTION

The Android Codefest Germany is a challenge on optimizing your existing Android NDK app on x86 processor or on building one. It's still open until Sunday, November 24th, you can submit your app here: http://androidcodefest.bemyapp.com

TRANSCRIPT

Page 1: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Adding x86 target to your Android App

Xavier Hallade, Technical Marketing Engineer, Intel

Page 2: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

What we are working on for Android*

Key AOSP and Kernel Contributor

Optimized Drivers & Firmware

Highly Tuned Dalvik Runtime

Porting and Optimizing

Browser and Apps

NDK Apps Bridging Technology

64-Bit

64bit

Page 3: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Our devices are already fully compatible with

established Android* ecosystemAndroid* Dalvik* apps

These will directly work, Dalvik has been

optimized for Intel® platforms.

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

Android Runtime

Core Libraries

Dalvik Virtual

Machine

Most of the time, it just works !

Page 4: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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.

Page 5: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Intel® devices on the market

Page 6: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Smartphones with Intel Inside - 2012

Motorola* RAZR i ZTE* Grand X IN

Lava* Xolo X900 Megafon* Mint

Lenovo* K800

Orange* San Diego (UK)

Orange* avec Intel Inside (FR)

Z2460

Page 7: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Smartphones with Intel Inside - 2013

Intel® Yolo

Acer* Liquid C1

Z2420 Z2580Z2560

Lenovo* K900 – 5.5”

ASUS Fonepad™ Note FHD - 6”

ZTE* Grand X2 In – 4.5”

ZTE* Geek – 5”

Etisalat E-20*

Page 8: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Tablets with Intel Inside - 2013

ASUS* MeMO Pad FHD 10”

(Z2560)

ASUS* Fonepad™ 7”

(Z2420/Z2560)

Dell* Venue 7/8

(Z2560)

Samsung* Galaxy™ Tab 3 10.1”

(Z2560)

LTE version now available

Page 9: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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

Page 10: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

How to target multiple platforms (incl. x86)

from NDK apps ?

Page 11: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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

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

Configuring NDK Target ABIs

ARM v7a libs are built

ARM v5 libs are built

x86 libs are built

mips libs are built

Put APP_ABI=all inside

Application.mk

Run ndk-build…

Page 12: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

PSI

TS

PIDs

Packaging APKs for Multiple CPU Architectures

Two options:

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)

Page 13: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Fat Binaries

By default, an APK contains libraries for every supported ABIs.

Use lib/armeabi libraries

Use lib/armeabi-v7a

libraries

Use lib/x86

libraries

libs/armeabi-v7a

libs/x86

libs/armeabi

APK file

The application will be filtered during installation (after download)

Recommended

Page 14: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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

Page 15: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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.

Page 16: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Uploading Multiple APKs to the store

Don’t forget to use different version codes for your different APKs.

Page 17: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Third party libraries x86 support on

Android*

Page 18: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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

Page 19: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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

Page 20: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Porting processor specific code to x86 on

Android*

Page 21: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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

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

//******* 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

//…

Intel® Streaming SIMD Extensions (Intel® SSE)Supplemental Streaming SIMD Extensions (SSSE)

Page 22: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Memory Alignment

By default

Easy fix

struct TestStruct {

int mVar1;

long long mVar2;

int mVar3;

};

struct TestStruct {

int mVar1;

long long mVar2 __attribute__ ((aligned(8)));

int mVar3;

};

Page 23: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Optimizing for x86 platforms

Page 24: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

VectorizationSIMD instructions up to SSSE3 available on current Intel® Atom™ processor based platforms, Intel® SSE4.2 on the next one that uses Silvermont Microarchitecture

On ARM*, you can get vectorization through the ARM NEON* instructions

Two classic ways to use these instructions:

Compiler auto-vectorization

Compiler intrinsics

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

SSSE3, SSE4.2Vector size: 128 bit

Data types:

• 8, 16, 32, 64 bit integer

• 32 and 64 bit float

VL: 2, 4, 8, 16

X2

Y2

X2◦Y2

X1

Y1

X1◦Y1

X4

Y4

X4◦Y4

X3

Y3

X3◦Y3

127 0

Intel® Streaming SIMD Extensions (Intel® SSE)

Supplemental Streaming SIMD Extensions (SSSE)

Page 25: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

GCC Flags

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

ifeq ($(TARGET_ARCH_ABI),x86)

LOCAL_CFLAGS += -O3 -ffast-math -mtune=atom -mssse3 -mfpmath=sse

else

LOCAL_CFLAGS += ...

endif

NDK_TOOLCHAIN_VERSION=4.8

LOCAL_CFLAGS += -O3 -ffast-math -mtune=slm -msse4.2 -mfpmath=sse

To optimize for Intel Silvermont Microarchitecture (available starting with NDK r9

gcc-4.8 toolchain):

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

Page 26: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Debugging

Page 27: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Debugging with logcatNDK provides log API in <android/log.h>:

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);

int __android_log_print(int prio, const char *tag,

const char *fmt, ...)

Page 28: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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

Page 29: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Debugging with GDB and EclipseNative 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.

Page 30: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Debugging with GDB and Eclipse*

When NDK_DEBUG=1 is specified, a “gdbserver” file is added to your

libraries

Page 31: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Debugging with GDB and Eclipse*

Debug your project as a native Android* application:

Page 32: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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

Page 33: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

ValgrindThe 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.

Page 34: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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

Page 35: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Valgrind Screenshot

Page 36: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Valgrind on Android x86Installing Valgrind

Download this package: https://my.syncplicity.com/share/7cse0vnb43auckm/valgrind-x86-android-emulator

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.

Page 37: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Tools for Android* apps developersHAXM, TBB, GPA, XDK and others

Most of our tools are relevant even if you’re not targeting x86 platforms!

Page 38: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Intel x86 Emulator

Accelerator

Intel x86 Atom

System Image

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

Page 39: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

ARM and x86 Emulators running AnTuTu*

Benchmark

Page 40: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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

Page 41: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Intel® TBB - Example

#include <tbb/parallel_reduce.h>

#include <tbb/blocked_range.h>

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;

}

Computes reduction

over a range

Defining a one-

dimensional range

Lambda function with

range and initial value as

parm

Calculating a part of Pi

within the range r

Defining a reduction

function

Page 42: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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

Page 43: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

1. Install APK, and

connect to Host

PC via adb

2. Run Intel® GPA System

Analyzer on

development machine

3. View Profile

Intel® Graphics Performance Analyzers

Page 44: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

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">

Page 45: [Android Codefest Germany] Adding x86 target to your Android app by Xavier Hallade

Other tools and libs for Android*

• Intel Beacon Mountain

• Intel IPP Preview

• Intel Compiler

• Intel XDK New

• Project Anarchy