How to port an NDK Android * Application

Source: Internet
Author: User

Overview

This guide is used to help developers port existing ARM *-based NDK applications to x86. If you already have a running application, you need to know how to quickly find your application on the x86 device in the Android * Market. This article will provide you with some entry-level information. This Guide also provides some tips and guidelines to help you solve compiler problems that may occur during the porting process.

Content
  1. Overview
  2. NDK Overview
    • JNI performance impact and overhead
    • Obtain NDK
    • Introduction to NDK internal components
      • Makefiles
      • Command Line Construction
      • Process native library files
      • Runtime Verification
    • Summary
  3. Porting Overview
  4. Porting skills: from ARM * To x86
    • Tool chain compatibility
    • Memory alignment impact: Comparison between ARM * And intel
    • Floating-point budget: Comparison between ARM * and Intel lingdong
    • Port the ARM * NEON * command to Intel's intel SSE
      • What is NEON?
      • SSE: similar tools released by Intel
      • Comparison of NEON and SSE at the Assembly level
      • Comparison between NEON and SSE on the C/C ++ Layer
  5. Conclusion

 

NDK Overview

Native Development Kit NDK is a powerful tool that combines the powerful features of native x86 code with the GUI of Android * applications. By using this tool, developers will be able to improve the performance of some applications, but at the same time, developers also need to be very careful, because in some cases cannot achieve the expected results.

NDK is dedicated to supporting developers to do the following:

  • Compile the native C/C ++ Library (called by the Java * code of the package) for use in the Android * application package.
  • Recompile the ARM * native library for use on the x86 Platform (Intel lingdong micro-architecture) and Port the library as necessary

For the second point mentioned above, you may only need to modify the Build Flag and re-compile it, but sometimes it is not that simple. For example, if the native library involves embedded assembly in the C code, the code will not be able to implement the goal of freely running two different architectures through simple compilation, in this case, you need to rewrite the Code (for more information, see the section comparing NEON * of ARM * and Intel SSE ).

JNI performance impact and overhead

Java * Native Interface (JNI) combines Android * Java * code with native code pre-compiled by NDK. For more information about this interface, visit: http://java.sun.com/docs/books/jni /.

The above link provides a wide and in-depth analysis of the JNI specification. If you only want to know its overview, the Wiki page can meet your requirements (if you have any questions, please refer to the specifications at any time to check its correctness ). The URL of the Wiki page is as follows: http://en.wikipedia.org/wiki/java_native_interface.

JNI has a huge overhead. Therefore, ideally, developers should minimize JNI calls in applications. Specifically, using native code in Android * applications does not necessarily improve performance. Generally, when the native code involves operations performed by the CPU (such as using a large number of SSE commands), performance can be improved. However, in other cases, if the existing application is only used to provide users with complex Web interfaces, using native code through JNI may reduce the performance. There are no written rules on when to use and when not to use NDK. the preceding rules only provide some general principles and issues that need attention.

Obtain NDK

Developers can obtain the latest NDK version at http://developer.android.com/sdk/ndk/index.html. In the latest version of NDK r6b, NDK can be used to build native libraries based on ARM * and x86 (Intel Atom micro-architecture. This facilitates developers to port native code in an application package.

Introduction to NDK internal components Makefiles

Developers will need to create an Android. mk file and an Application. mk file for the project (optional ). The Application. mk file describes the native modules required by your Application. The Android. mk file is used to control how and where to build a module (static/Shared library ). The following is a simple snippet of the Android. mk file:


Figure 1: content of the simple Android. mk File

 

When the system is built, a database is prefixed and a library named libtest. so is generated at the same time. As expected, the developer will name the project source file in LOCAL_SRC_FILES. LOCAL_LDLIBS and LOCAL_CFLAGS are used to specify the Linking Flag and Compilation Flag respectively ).

Command Line Construction

The following command line provides an example of how to specify the build point to the x86 architecture: ndk-build APP_ABI = x86

The following two methods can be used to call the native Library: System. loadLibrary ("relative_path_and_name") and System. load ("full_path_to_lib_file "). The former is more common and the latter is more stable. When the former is used, the "lib" part of the library name specified by Android. mk can be discarded. Call example:


Figure 2: Example of calling native code

 

In addition, for native code, developers need to ensure that the native code input method has the correct JNIEXPORT method signature, rather than the typical C/C ++ header. The JNI link mentioned above contains more information.

Process native library files

Developers can load the native library in two ways: 1) provide the library in the Android * apk package and reference it during runtime; 2) provide the absolute path to the library on the Android * file system. Which of the above methods is determined by developers' preferences. However, no matter which method is used, the corresponding correct processing should be performed.

Runtime Verification

By using the adb logcat command, developers can ensure that the target native library is successfully loaded at runtime. The following provides an example to describe the system logs loaded by the native library. Note that you must provide the complete path to the native library file.


Figure 2: Example of calling native code

Summary

The above sections provide an introduction to how to use NDK. For more details, see the relevant documents contained in the NDK application package. These documents provide excellent tutorials and source code examples for various applications.

Porting Overview

For most applications, porting existing NDK applications to x86 is very simple. Unless the native code uses the unique features of ARM *, you only need to re-compile, re-package, and re-publish the application.

The following describes how to port an NDK application to x86.

  1. Obtain the latest NDK tool. X86 support was first available in android-ndk-r6, but there were still some problems that Google soon fixed. Make sure that you have downloaded and installed the latest NDK from the Android * NDK website (when writing, the latest NDK is a android-ndk-r6b.

     

  2. If you already have an Application. mk file, you can edit the APP_ABI line to add it to x86. Example:

    APP_ABI: = armeabi armeabi-v7a x86

    If you do not have the Application. mk file, you can add x86 to the command line component. The following is the command line and output content used to build an NDK sample application.
    $ Ndk-build APP_ABI = "armeabi armeabi-v7a x86"

    Install: test-libstl => libs/armeabi/test-libstl
    Install: test-libstl => libs/armeabi-v7a/test-libstl
    Install: test-libstl => libs/x86/test-libstl
  3. In the previous step, we can find that folders containing binary code of each architecture are created under the Libs directory. Next, we will re-package the APK to include the new library. Because the Libs directory is located under the root project folder, the build tool used to create the APK already knows the binary code in the folder. With Eclipse, you can simply re-build the project APK to include the new x86 binary code. You can use the command line to perform the same operations. The following lists the sample output when the rebuilding example demonstrates hello-jni:

    $ Android. bat update project -- path C:/Tools/android-ndk-r6b/samples/hello-jni
    Updated local. properties
    Added file C: \ Tools \ android-ndk-r6b \ samples \ hello-jni \ build. xml
    Added file C: \ Tools \ android-ndk-r6b \ samples \ hello-jni \ proguard. cfg
    $ Ant-f hello-jni/build. xml debug
    Buildfile: C: \ Tools \ android-ndk-r6b \ samples \ hello-jni \ build. xml
    ...
    Debug:
    [Echo] Running zip align on final apk...
    [Echo] Debug Package: android-ndk-r6b \ samples \ hello-jni \ bin \ HelloJni-debug.apk
    BUILD SUCCESSFUL
  4. The next step is to run and Test on Intel architecture devices or x86 simulators. The last step to verify that all binary codes are correctly packaged is to use the zip archive tool to open the APK and ensure that it contains binary code. The following is a screenshot of the APK structure when the x86 binary code exists.

Porting skills: from ARM * To x86

Porting an application to x86 should be very simple. Although many people may have this idea, in actual code, you still need to pay attention to and resolve the differences between Intel's lingdong and ARM * architectures. The following topic describes the problems you may encounter during the transplantation process and how to solve them.

Tool chain compatibility

Your build environment may directly use the tool chain instead of the Android * build script. In ARM *, the path used is as follows:

Android-ndk \ toolchains \ arm-linux-androideabi-4.4.3
For x86, use the following path:
Android-ndk \ toolchains \ x86-4.4.3
For more information, see the ndk documentation at android-NDK/docs/STANDALONE-TOOLCHAIN.html.

Memory alignment impact: Comparison between ARM * And intel

Memory alignment mismatch may occur when C/C ++ code is transplanted between ARM * and Intel's lingdong microarchitecture. The following article provides a typical example of this:/en-us/blogs/2011/08/18/understanding-x86-vs-arm-memory-alignment-on-android. The main point is that developers should consider explicit forced Data Alignment as necessary when designing code. Otherwise, developers cannot ensure that data can be correctly processed on different platforms.

Floating Point budget: Comparison between ARM and intel

Currently, three supported application binary interfaces (ABI) can be used to build the NDK Library ):

  1. 'Armeabi '-default option. A library is created for devices based on ARM * v5TE. Floating-point operations with such goals use software floating-point operations. The binary code created using this ABI can run on all ARM * devices.
  2. 'Armeabi-v7a '-creates a library for devices that support ARM * v7 and uses the hardware FPU command.
  3. 'X86 '-generated binary code supports IA-32 instruction sets that contain hardware-based floating point operations.

All these ABI options support floating point operations. Unless ARM *-specific Assembly commands are used, code porting to x86 will not cause problems. The advantage is that if your application is only compiled for "armeabi" and now supports x86, you can feel the performance improvement when performing most floating point operations.

Port the ARM * NEON * command to Intel's intel SSE

Although this short article is not all-encompassing, the following information will give you a general idea of how SIMD extensions are implemented in Intel architecture and ARM. With this introduction, developers will also get some tools to start some simple coding exercises.

What is NEON?

NEON * is an ARM * Technology Used in multimedia applications (such as smartphones and HDTV. ARM * indicates its 128-bit SIMD-based technology-ARM * Cortex * (a serial extension)-provides at least three times higher performance than the ARM * v5 architecture, and at least twice the performance of ARM * v6. To learn more about this technology for NEON and other performance considerations, visit the following url: http://www.arm.com/products/processors/technologies/neon.php

The key concept here is that each register is "stacked" into a vector, where each register is an element and matches the Data Type of other elements. This method is called Packed SIMD.

SSE: similar tools released by Intel

SSE refers to the SIMD stream instruction extension for Intel architecture (IA. Currently, Intel lingdong supports SSSE3 (supplemented with SIMD stream command extension 3 ). Currently, the system does not support SSE4.x. The latter is also a 128-bit engine for packaging floating point data. This execution mode starts with MMX technology. SSx is a newer technology that replaces MMX. For more information, see Chapter 1: infrastructure in the Intel IA-32 and IA-64 software developer manual. URL: http://www.intel.com/content/www/cn/zh/processors/ubuntures-software-#-manuals.html. Currently, the SSE overview section is in section 5.5. It provides operation codes for SSE, SSE2, SSE3, and ssse3. Note that data operations usually involve processing precision-based packaged floating point values, and data needs to be transferred in batches between XMM registers or between these registers and memory. XMM registers are mainly used to replace MMX registers.

Comparison of NEON and SSE at the Assembly level

While we recommend that you use the aforementioned intel architecture software developer manual to learn about all the individual SSE (x) aids, we also encourage developers to learn about various SSE assembly-level commands through the following links, URL: http://neilkemp.us/src/sse_tutorial/sse_tutorial.html.

In this link, you can directly jump to the sample code through the "directory" section or first learn more about some background information. Similarly, the following provides some information directly from the ARM * manual and a small segment of the NEON * Assembly:/sites/default/files/m/B/4/c/DHT0002A_introducing_neon.pdf. See section 1.4 in the ARM * document.

The following are several key points for comparing NEON and SSE assembly code at a general level (Note: With the development of technology, information will be outdated at any time; based on the specific SIMD technology and the current application coding problems, there may be other differences ):

Byte storage order. Intel only supports low-level priority assembly, while ARM * supports both high-level and low-level priorities (ARM * supports two orders ). In the provided code example, like intel, ARM * Code uses low priority. Note that, however, some compiler effects may exist in ARM *. For example, the-mlittle-endian and-mbig-endian labels are available when GCC * is used for ARM * Compilation. For more information, visit: http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html

Granularity. when referencing a simple assembly code example (note that this does not include all the differences between the NEON and SSE that developers may find), add the ADDPS command of SSE to the VADD of NEON. ix (I .e., x = 8 or 16) for comparison. Note that the latter reduces the granularity of data to be processed as part of the reference mnemonic.

Comparison between NEON and SSE on the C/C ++ Layer

When porting the C/C ++ code NEON code to SSE, Many API problems may occur. Note the assumption in this article that the embedded assembly is not used, but the real C/C ++ code is used.

For higher-level programming, the difference between NEON and SSE involves processing large-size data (128 bits. This article provides a short example for this porting exercise: http://stackoverflow.com/questions/7203231/neon-vs-intel-sse-equivalence-of-certain-operations

Conclusion

We hope this guide will provide you with some practical information to help you successfully port NDK-based applications to x86. After porting to x86, your applications can be downloaded, purchased, and used by a brand new Android * device. If you have any problems during the migration process, please comment in this article at any time. We will be happy to answer your questions and help you.

Related Articles and resources:

  • More details about how to use SSE commands in Android * media applications on Intel's lingzhu Platform
  • How to port an NDK Android * Application
  • Android * NDK for Intel architecture
Statement

* Other names and brands may be assets of other owners.

Intel reserves all rights reserved on April 9, 2011. Retain ownership.

Intel, Atom, and lingdong are trademarks of intel in the United States and/or other countries.

This document contains information about Intel products. This document does not constitute authorization for any intellectual property rights, including express, implied, or based on the Anti-statement principle or others. Intel is not liable for any other responsibilities. Intel hereby disclaims: this document does not constitute any express or implied warranty of Intel regarding the use and/or sale of its products, including) any liability or warranty for the applicability of a specific purpose, the (ii) merchantability and (iii) Infringement of any patent, copyright or other intellectual property rights.

Intel products are intended for or used for the following applications without the prior written consent of Intel: In such applications, personal injury or death may be caused by faults of Intel products.

Intel has the right to change the product specifications and descriptions at any time without notice. The designer shall not trust any feature not available to the English product, nor shall the designer trust any description or feature description marked with "reserve right" or "undefined. In this regard, Intel reserves the right to define it in the future. At the same time, Intel shall not assume any responsibility for conflicts and incompatibility arising from its subsequent changes to such descriptions or feature descriptions. The information provided here can be changed at any time without notice. Do not design a product based on the information provided in this document.

The products described in this document may contain design defects or errors that make them inconsistent with the declared specifications. These defects or errors are included in the error table and can be obtained upon request.

Before placing an order, contact your local intel business department or distributor to obtain the latest product specifications.

To obtain a copy of the document with serial numbers or other intel literature involved in this article, call 1-800-548-4725, or visit: http://www.intel.com/design/literature.htm

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.