10 Android NDK Tips

来源:互联网 发布:阿里云测工作 编辑:程序博客网 时间:2024/06/10 03:01

10 Android NDK Tips

http://blogs.arm.com/software-enablement/238-10-android-ndk-tips/

With new devices and new capabilities being exposed by the Android NDK (Native Development Kit) it is now possible to really get the best out of these ARM based devices. Here are a few quick tips to help that along.

1 - Stay on Target

The newest devices are generally ARMv7, meaning that it can pay to use v7 builds and features. The latest version of the NDK adds support ARMv7 and NEON code allowing key loops and media operations to be optimized far beyond what would otherwise be possible. The NDK provides a small static library that will allow you to identify what options you have at runtime. For examples of how to use these features, look at the hello-neon example project in the samples directory of the NDK

The older devices are v6, but the NDK does not specifically support it, leaving you with the choice of building safely for v5TE or taking the risk that there may be v5TE devices out there. If you need every iota of speed, and know what hardware you are targeting, then it may be worth building for v6. The newest devices, supporting Android 2.0 and up, seem generally to be ARMv7 based, although you cannot rule out enthusiasts porting the newer OS releases onto the older hardware. When given a choice, it is better to concentrate on an ARMv7 with NEON implementation.

2 - Do not optimize immediately

Unless you plan on porting an existing C++ application, do not rush into native. Get the app right first and profilecarefully. Often things you think will be bottlenecks are less of a factor than other features. Recent handheld devices incorporate two levels of cache and sometimes clock-scaling designed to conserve power. Combine that with ongoing efforts by Google to improve the performance of the OS and there is ample scope for surprises.

3 - Optimize like a ninja

Aim to leave no trace. It can be tempting to rip apart your design in favour of a few extra cycles, but other than in exceptional cases this is something to avoid. When you do optimize, sneak in, turn the key bits of your application into super-fast native or assembly code and get out cleanly. That way you should not compromise your maintainability and ease of debugging. Of course if you are sure a redesign is likely to buy you enough speed to be worth the pain then get out the hacksaw.

4 - Re-factor around your optimisations

Once you have a design in place, do not be afraid to re-arrange code to make more of it suitable for optimising, but avoid tinkering too much with native code once it is working. The Java code is more easily rearranged and debugged. Often it will make sense to optimize at the Java level first with a view to consolidating chunks of logic ready for turning native. Changes in algorithm or data structures at the Java level should generally carry over as an advantage when porting to native and are much easier to work with.

5 - Maintain a Java fall-back

Executing unsupported native code is a bad idea; at best it will cause your application to exit unexpectedly. It is possible to determine with some confidence whether or not your native code will be compatible with the device the program is running on, so as long as you have a Java implementation available you can always fall back to that. This is where the optimized Java version from tip 4 pays off extra.

6 - Allocate with care

Whenever possible allocate in Java anything that is needed in Java rather than relying on later, easily forgotten, calls to C to free. This minimises the chances of leaks and makes the Java code simpler. Where you have a significantly long-running operation it will make sense to allocate locally for scratch space, but watch your pointers - the old C habits around pointer discipline can fade a bit too quickly if you are writing a lot of Java code.

7 - Multi-thread with great care

We already have several development platforms with multiple ARM cores, so they may well be in your customers hands soon than you think. With that in mind it is tempting to split everything up into threads. It is a good idea in general, but remember maxing out the load on your system may speed up the result at the expense of the second-to-second user experience. Even so, used sensibly threads can be very effective. The Android system already produces several threads itself just to run one app, while they are generally just waiting on events if you create too many actively executing threads of your own you may hamper their ability to run and inadvertently degrade the overall user experience.

8 - Thread at the Java Level

When you do break your logic into threads, it is better to do it via Java than pthreads wherever possible. There are fewer hazards and more language-level tools for managing access with the Java VM. If the set-up cost worries you, it is not going to be hard to use a small ready-constructed pool of workers. Remember to post updates on long-running tasks back to the main UI thread to keep the user informed. You also want to remember one of the most important Android NDK rules: NEVER run your native code on the UI thread. In fact, try to run almost no Java code on the UI thread; Android has appropriate APIs (check the Handler class) to allow cheaply pushing tasks onto threads that are not the UI Thread.

9 - Know when to use Assembler

C or C++ will give you an instant speed-up without making the code that much more difficult to maintain than Java. Further incremental improvement may be possible from converting key bits of code to assembler, but weigh the time and effort concerned against the benefit you expect. It is better to ship working code now and release a faster update later than spend forever tuning. Having said that, sometimes if you know exactly what you want to do you can get significant additional performance.

Always check the code GCC is putting out first, it may be doing a lot better -- or a lot worse -- than you expect. Hereobjdump is a valuable tool, a version is already provided in build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/bin directory of the NDK download from Google.

10 - Know when to use NEON

NEON is a very powerful tool, with the potential to give up to 8x performance improvement over optimized assembler in the right circumstances, but it is not suitable for everything. To learn how to best make use of NEON, take a look at the NEON guides on this blog.

  • NEON Loads and Stores
  • Dealing with leftovers


Dave, Principal Engineer, ARM, For at least the last ten years he has been maintaining, optimising, examining or attempting to answer hardware engineers questions about Virtual Machines. After several years of working on Java, with time off to work on tools, he now tries to understand Android.

Shortlink to this post: http://bit.ly/abiLKd

原创粉丝点击