Increasing performanceof big arrays processingon Android... cannot come up with a shorter title ...
The StoryJava (SDK)C++ (NDK)vs ?OpenSL ES APIAudioTrack API
Application base conceptsshort[]track.write(...);
Main operationfor (int outIdx = start; outIdx < end; outIdx++){// ...output[outIdx] = source[srcIdx];// optional: pitch sh...
Implementation● Think about avoiding GC● Think more about avoiding GC● Think a lot about avoiding GC● Utilize RenderScript
RenderScript● Can be used not only for images processing● Our implementation switches from pure Javato RenderScript when p...
And it worked fast enough! On tablets...http://hdwpapers.com/ship_silversea_shadow_wallpaper-wallpapers.html
But then we ran it on budget phones...http://www.theatlantic.com/infocus/2012/01/the-wreck-of-the-costa-concordia/100224/
Optimizations time!
http://ericlanke.blogspot.com/2012/11/too-big-to-measure.htmlMeasure
Traceview1. Generate trace logs withDebug.startMethodTracing("my")or DDMS2. View traces with$traceview my.trace
Traceview
AspectJpublic aspect BenchmarkAspect {pointcut benchmarkPointcuts() :execution(* audio.Voice.fill(..));Object around() : b...
AspectJ● Allows to wrap execution of methods we areinterested in● Works on Android with compile timeweavements
Our instruments● Traceviewfor detecting slowest parts of our code● AspectJfor more precise measuring of executiontime
http://www.allstuffpics.net/2011/04/wallpaper-bike-and-cars-collection-hd.htmlAct
Main operationfor (int outIdx = start; outIdx < end; outIdx++){// ...output[outIdx] = source[srcIdx];// optional: pitch sh...
Using NDK● Main point:rewriting critical parts in C++ helps● JNI calls overhead was negligible in ourcase
Java implementation
C++ implementation10 times!
Main operationfor (int outIdx = start; outIdx < end; outIdx++){// ...output[outIdx] = source[srcIdx];// optional: pitch sh...
Fixed point arithmeticstypedef int32_t ffloat;#define FRAC_BITS 10const ffloat ONE = 1 << FRAC_BITS;static inline ffloat i...
After all optimizations...GC: 14.7%
Solution● Moving sample buffers to native heapcompletely
Java sidepublic class Buffer {private int nPointer;public Buffer() { nPointer = nativeInit(); }public void doSomething() {...
Native sidejint XXX_nativeInit() {NativeBuffer* b = new NativeBuffer();return (jint)b;}void XXX_nativeDo(jint np) {NativeB...
http://www.citizenship-aei.org/2012/04/americans-failing-citizenship-test-again/Dont forget to test
Tests● Robolectric based tests for major part ofaudio engine components● Android instrumentation tests forRenderScript and...
Thank you!Roman MazurHead of Android/Java Unit at Stanfymazur.roman@gmail.com+Roman Mazur@roman_mazur
Upcoming SlideShare
Loading in...5
×

Android Developer Days: Increasing performance of big arrays processing on Android

978

Published on

Presentation by Roman Mazur, senior Android Developer at Stanfy at Android Developer Days in Ankara, June 2013. This presentation dedicated to techniques of optimization of big arrays processing using Android NDK and RenderScript.

Published in: Education, Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
978
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
13
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Android Developer Days: Increasing performance of big arrays processing on Android

  1. 1. Increasing performanceof big arrays processingon Android... cannot come up with a shorter title ...
  2. 2. The StoryJava (SDK)C++ (NDK)vs ?OpenSL ES APIAudioTrack API
  3. 3. Application base conceptsshort[]track.write(...);
  4. 4. Main operationfor (int outIdx = start; outIdx < end; outIdx++){// ...output[outIdx] = source[srcIdx];// optional: pitch shifting calculations}
  5. 5. Implementation● Think about avoiding GC● Think more about avoiding GC● Think a lot about avoiding GC● Utilize RenderScript
  6. 6. RenderScript● Can be used not only for images processing● Our implementation switches from pure Javato RenderScript when possible● Reuse Allocations
  7. 7. And it worked fast enough! On tablets...http://hdwpapers.com/ship_silversea_shadow_wallpaper-wallpapers.html
  8. 8. But then we ran it on budget phones...http://www.theatlantic.com/infocus/2012/01/the-wreck-of-the-costa-concordia/100224/
  9. 9. Optimizations time!
  10. 10. http://ericlanke.blogspot.com/2012/11/too-big-to-measure.htmlMeasure
  11. 11. Traceview1. Generate trace logs withDebug.startMethodTracing("my")or DDMS2. View traces with$traceview my.trace
  12. 12. Traceview
  13. 13. AspectJpublic aspect BenchmarkAspect {pointcut benchmarkPointcuts() :execution(* audio.Voice.fill(..));Object around() : benchmarkPointcuts() {storeStartTime();try {return proceed();} finally {storeEndTime(); // and write to log}}}
  14. 14. AspectJ● Allows to wrap execution of methods we areinterested in● Works on Android with compile timeweavements
  15. 15. Our instruments● Traceviewfor detecting slowest parts of our code● AspectJfor more precise measuring of executiontime
  16. 16. http://www.allstuffpics.net/2011/04/wallpaper-bike-and-cars-collection-hd.htmlAct
  17. 17. Main operationfor (int outIdx = start; outIdx < end; outIdx++){// ...output[outIdx] = source[srcIdx];// optional: pitch shifting calculations}
  18. 18. Using NDK● Main point:rewriting critical parts in C++ helps● JNI calls overhead was negligible in ourcase
  19. 19. Java implementation
  20. 20. C++ implementation10 times!
  21. 21. Main operationfor (int outIdx = start; outIdx < end; outIdx++){// ...output[outIdx] = source[srcIdx];// optional: pitch shifting calculations}
  22. 22. Fixed point arithmeticstypedef int32_t ffloat;#define FRAC_BITS 10const ffloat ONE = 1 << FRAC_BITS;static inline ffloat int_to_ffloat(jint v) {return (ffloat)(v << FRAC_BITS);}static inline ffloat float_to_ffloat(jfloat v) {register jint intpart = (jint) v;return int_to_ffloat(intpart)+ (ffloat)((v - intpart) * ONE);}25%faster
  23. 23. After all optimizations...GC: 14.7%
  24. 24. Solution● Moving sample buffers to native heapcompletely
  25. 25. Java sidepublic class Buffer {private int nPointer;public Buffer() { nPointer = nativeInit(); }public void doSomething() { nativeDo(nPointer); }protected void finalize() {super.finalize();nativeFinalize(nPointer);}private static native int nativeInit();private static native void nativeFinalize(int np);private static native void nativeDo(int np);}
  26. 26. Native sidejint XXX_nativeInit() {NativeBuffer* b = new NativeBuffer();return (jint)b;}void XXX_nativeDo(jint np) {NativeBuffer* b = (NativeBuffer*)np;b->nativeMethodCall();}void XXX_finalizeNative(jint np) {NativeBuffer* b = (NativeBuffer*)np;delete b;}
  27. 27. http://www.citizenship-aei.org/2012/04/americans-failing-citizenship-test-again/Dont forget to test
  28. 28. Tests● Robolectric based tests for major part ofaudio engine components● Android instrumentation tests forRenderScript and native implementations.
  29. 29. Thank you!Roman MazurHead of Android/Java Unit at Stanfymazur.roman@gmail.com+Roman Mazur@roman_mazur
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×