Strategies to improve embeddedLinux applications’ performance   beyond ordinary techniques         Anderson Medeiros      ...
Agenda•  The performance problem faced by Motorola’s IM team•  Linux’s Dynamic Loader•  Prelink•  Libraries Tools•  Dymica...
Motivation
Our Problem
The basic recipeMeasureAnalyzeOptimize
Our DiscoverUser clicks   fork()                    main()   Screen.show()                       DYNAMIC LOADER           ...
Linux’s Dynamic Loader
Loading a dynamically                              linked program   .interp                                        ALoad d...
A closer look at relocation  Relative              Symbol-based               Type                                        ...
prelink
Motivation
How does prelink work? I•  Collects ELF binaries which should be prelinked and all the ELF   shared libraries they depend ...
How does prelink work? II•  At runtime, the dynamic linker first checks if it is prelinked itself•  Just before starting a...
Results          t
Library tools
How to use prelink?•  prelink –avf --ld-library-path=PATH --dynamic-linker=LDSO   •  -a --all       •  Prelink all binarie...
Dynamically Loading Libraries
Motivation
Motivation IIIf there are any libraries you are going to use   only on special occasions, it is better to load   them when...
The Basics#include <dlfcn.h>void*   dlopen    ( const char* filename, int flags);void*   dlsym     ( void* handle, const c...
Loading C++ Libraries                                C++ uses mangling!int mod (int a , int b);                 _Z3sumiifl...
The exampleclass Foo{     public:        Foo(){}        ~Foo(){}        void bar(const char * msg)        {           std:...
The solutionStep 1 Define an interface for your class.                                 Foo                         + Foo()...
The solutionStep 1 Define an interface for your class.                              <<interface>>                         ...
The solution - Lib’s Header fileStep 1 Define an interface for your class#ifndef FOO_H__#define FOO_H__class Foo{    publi...
The solution - Lib’s Header fileStep 2 Create “C functions” to create and destroy instances  of your classStep 3 You might...
The solution - Lib’s Implementation fileStep 4 Implement your interface and “C functions” #include "foo.h"                ...
The solution - The program#include <foo.h>#include <assert.h>#include <dlfcn.h>int main(){   void* handle = dlopen("./libf...
Tunning Shared Libraries
Inspiration     “How To Write Shared Libraries”          Ulrich Drepper- Red Hathttp://people.redhat.com/drepper/dsohowto....
Less is always betterKeep at minimum…•  The number of libraries you directly or indirectly depend•  The size of libraries ...
Search directories for libs
Reducing search spaceStep 1 Set LD_LIBRARY_PATH to emptyStep 2 When linking use the options:   -rpath-link <dir> to the sp...
Reducing exported symbolsUsing GCC’s attribute feature int localVar __attribute__((visibility(“hidden”))); int localFuncti...
Reducing exported symbols II{                                You can tell the linker which    global:                     ...
Pro and Cons                Pros                                        ConsVisibility attribute                         V...
Restricting symbol string’s lenghtnamespace java{    namespace lang    {       class Math       {         static const int...
Avoiding relocations  char* a = “ABC”;                    A B C 0                          .dataconst char a[] = “ABC”;   ...
UI Time perception
MotivationX hours to deliver    X hours to deliver    $ to ship             $ to shipPackage tracking         No tracking
Motivation II
Improving responsivenessIt is not always possible to optimize code because:•  You might not have access to problematic cod...
Can I postpone ?loading Plug-Ins …
Can I postpone ?            Loading            plug-ins
Can I parallelize?
Can I parallelize?Sending file…
Can I remove it ?
In conclusion …•  You learned that libraries may play an important role in the startup   performance of your application;•...
Q&A
Strategies to improve embedded Linux application performance beyond ordinary techniques
Upcoming SlideShare
Loading in...5
×

Strategies to improve embedded Linux application performance beyond ordinary techniques

605

Published on

he common recipe for performance improvement is to profile an application, identify the most time-consuming routines, and finally select them for optimization. Sometimes that is not enough. Developers may have to look inside the OS searching for performance improvement opportunities. Or they might need to optimize code inside a third party library they do not have access to. For those cases, other strategies shall be used. This presentation reports the experiences of Motorola's Brazilian developers reducing the startup time of an application on Motorola's MOTOMAGX embedded Linux platform. Most of the optimization was performed in the binary loading stage, prior to the execution of the entry point function. This endeavor required use of Linux ABI and Linux Loader going beyond typical bottleneck searching. The presentation will cover prelink, dynamic library loading, tuning of shared objects, and enhancing user experience. A live demo will show the use of prelink and other tools to improve performance of general Linux platforms when libraries are used.

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

No Downloads
Views
Total Views
605
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
9
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Strategies to improve embedded Linux application performance beyond ordinary techniques

  1. 1. Strategies to improve embeddedLinux applications’ performance beyond ordinary techniques Anderson Medeiros Software Engineer, Motorola André Oriani Software Engineer, Motorola
  2. 2. Agenda•  The performance problem faced by Motorola’s IM team•  Linux’s Dynamic Loader•  Prelink•  Libraries Tools•  Dymically loading Libraries•  Tuning Shared Libraries•  UI Time Perception•  Q & A
  3. 3. Motivation
  4. 4. Our Problem
  5. 5. The basic recipeMeasureAnalyzeOptimize
  6. 6. Our DiscoverUser clicks fork() main() Screen.show() DYNAMIC LOADER t
  7. 7. Linux’s Dynamic Loader
  8. 8. Loading a dynamically linked program .interp ALoad dynamic linker .rel.text Relocation .rel.data .dynamic Libraries .initDependency libraries Program’s Symbol entry point tables A
  9. 9. A closer look at relocation Relative Symbol-based Type Lookup failed Symbol’sCompute hash Yes offset Lookup Hash Next No scopeAdd load bucket object empty address Yes Next Match element No No Adjust Chain Yes address empty
  10. 10. prelink
  11. 11. Motivation
  12. 12. How does prelink work? I•  Collects ELF binaries which should be prelinked and all the ELF shared libraries they depend on•  Assigns a unique virtual address space slot for each library and relinks the shared library to that base address•  Resolves all relocations in the binary or library against its dependant libraries and stores the relocations into the ELF object•  Stores a list of all dependant libraries together with their checksums into the binary or library•  For binaries, it also computes a list of conflicts and stores it into a special ELF section Note: Libraries shall be compiled with the GCC option -fPIC
  13. 13. How does prelink work? II•  At runtime, the dynamic linker first checks if it is prelinked itself•  Just before starting an application, the dynamic linker checks if: •  There is a library list section created by prelink •  They are present in symbol search scope in the same order •  None have been modified since prelinking •  There aren’t any new shared libraries loaded either•  If all conditions are satisfied, prelinking is used: •  Dynamic linker processes the fixup section and skips all normal relocation handling•  If at least one condition fails: •  Dynamic linker continues with normal relocation processing in the executable and all shared libraries
  14. 14. Results t
  15. 15. Library tools
  16. 16. How to use prelink?•  prelink –avf --ld-library-path=PATH --dynamic-linker=LDSO •  -a --all •  Prelink all binaries and dependant libraries found in directory hierarchies specified in /etc/prelink.conf •  -v --verbose •  Verbose mode. Print the virtual address slot assignment to libraries •  -f --force •  Force re-prelinking even for already prelinked objects for which no dependencies changed •  --ld-library-path=PATH •  Specify special LD_LIBRARY_PATH to be used when prelink queries dynamic linker about symbol resolution details •  --dynamic-linker=LDSO •  Specify alternate dynamic linker instead of the default
  17. 17. Dynamically Loading Libraries
  18. 18. Motivation
  19. 19. Motivation IIIf there are any libraries you are going to use only on special occasions, it is better to load them when they are really needed.
  20. 20. The Basics#include <dlfcn.h>void* dlopen ( const char* filename, int flags);void* dlsym ( void* handle, const char* symbol);char* dlerror (void);int dlclose (void* handle);#echo Although you don’t have to link against the library#echo you still have to link against libdl##gcc main.cpp -ldl -o program
  21. 21. Loading C++ Libraries C++ uses mangling!int mod (int a , int b); _Z3sumiifloat mod (float a, float b); _Z3sumff math.cpp math.o
  22. 22. The exampleclass Foo{ public: Foo(){} ~Foo(){} void bar(const char * msg) { std::cout<<"Msg:"<<msg<<std::endl; } };
  23. 23. The solutionStep 1 Define an interface for your class. Foo + Foo() + ~Foo() + void bar(const char*)
  24. 24. The solutionStep 1 Define an interface for your class. <<interface>> Foo + virtual void bar(const char*) = 0 FooImpl + Foo() + ~Foo() + void bar(const char*)
  25. 25. The solution - Lib’s Header fileStep 1 Define an interface for your class#ifndef FOO_H__#define FOO_H__class Foo{ public: virtual void bar (const char*) = 0;};
  26. 26. The solution - Lib’s Header fileStep 2 Create “C functions” to create and destroy instances of your classStep 3 You might want to create typedefs extern "C" Foo* createFoo(); extern "C" void destroyFoo(Foo*); typedef Foo* (*createFoo_t) (); typedef void (*destroyFoo_t)(Foo*); #endif
  27. 27. The solution - Lib’s Implementation fileStep 4 Implement your interface and “C functions” #include "foo.h" Foo* createFoo() #include <iostream.h> { return new FooImpl(); class FooImpl:public Foo } { public: void destroyFoo(Foo* foo) FooImpl(){} { virtual ~FooImpl(){} FooImpl* fooImpl = virtual void bar(const char * msg) static_cast<FooImpl*>(foo); { delete fooImpl; cout<<"Msg: "<<msg<<endl; } } };
  28. 28. The solution - The program#include <foo.h>#include <assert.h>#include <dlfcn.h>int main(){ void* handle = dlopen("./libfoo.so",RTLD_LAZY); assert(handle); createFoo_t dyn_createFoo = (createFoo_t)dlsym(handle,"createFoo"); assert(!dlerror()); Foo* foo = dyn_createFoo(); if(foo) foo->bar("The method bar is being called"); destroyFoo_t dyn_destroyFoo = (destroyFoo_t)dlsym(handle,"destroyFoo"); assert(!dlerror()); dyn_destroyFoo(foo); dlclose(handle); return 0;}
  29. 29. Tunning Shared Libraries
  30. 30. Inspiration “How To Write Shared Libraries” Ulrich Drepper- Red Hathttp://people.redhat.com/drepper/dsohowto.pdf
  31. 31. Less is always betterKeep at minimum…•  The number of libraries you directly or indirectly depend•  The size of libraries you link against shall have the smallest size possible•  The number for search directories for libraries, ideally one directory•  The number of exported symbols•  The length of symbols strings•  The numbers of relocations
  32. 32. Search directories for libs
  33. 33. Reducing search spaceStep 1 Set LD_LIBRARY_PATH to emptyStep 2 When linking use the options: -rpath-link <dir> to the specify your system’s directory for libraries -z nodeflib to avoid searching on /lib, /usr/lib and others places specified by /etc/ld.so.conf and /etc/ld.so.cache #export LD_LIBRARY_PATH=“” #gcc main.cpp -Wl,-z,nodeflib -Wl,-rpath-link,/lib -lfoo -o program
  34. 34. Reducing exported symbolsUsing GCC’s attribute feature int localVar __attribute__((visibility(“hidden”))); int localFunction() __attribute__((visibility(“hidden”))); class Someclass { private: static int a __attribute__((visibility(“hidden”))); int b; int doSomething(int d)__attribute__((visibility (“hidden”))); public: Someclass(int c); int doSomethingImportant(); };
  35. 35. Reducing exported symbols II{ You can tell the linker which global: symbols shall be exported cFunction*; using export maps extern “C++” { cppFunction*; *Someclass; Someclass::Someclass*; #g++ -shared example.cpp -o Someclass::?Someclass*; libexample.so.1 -Wl, Someclass::method* -soname=libexample.so.1 -Wl,- }; -version-script=example.map local: *;};
  36. 36. Pro and Cons Pros ConsVisibility attribute Visibility attribute•  Compiler can generate optimal •  GCC’s specific feature; code; •  Code become less readable;Export Maps Export Maps•  More practical; •  No optimization can be done by•  Centralizes the definition of library’s compiler because any symbol may API; be exported
  37. 37. Restricting symbol string’s lenghtnamespace java{ namespace lang { class Math { static const int PI; static double sin(double d); static double cos(double d); static double FastFourierTransform (double a, int b,const int** const c); }; _ZN4java4lang4Math2PIE } _ZN4java4lang4Math3sinEd} _ZN4java4lang4Math3cosEd _ZN4java4lang4Math20FastFourierTransformEdiPPKi
  38. 38. Avoiding relocations char* a = “ABC”; A B C 0 .dataconst char a[] = “ABC”; A B C 0 .rodata ELF
  39. 39. UI Time perception
  40. 40. MotivationX hours to deliver X hours to deliver $ to ship $ to shipPackage tracking No tracking
  41. 41. Motivation II
  42. 42. Improving responsivenessIt is not always possible to optimize code because:•  You might not have access to problematic code;•  It demands too much effort or it is too risky to change it.•  There is nothing you can do (I/O latency, etc…).•  Other reasons ...
  43. 43. Can I postpone ?loading Plug-Ins …
  44. 44. Can I postpone ? Loading plug-ins
  45. 45. Can I parallelize?
  46. 46. Can I parallelize?Sending file…
  47. 47. Can I remove it ?
  48. 48. In conclusion …•  You learned that libraries may play an important role in the startup performance of your application;•  You saw how dynamic link works on Linux;•  You were introduce to prelink and and became aware of its potential to boost the startup;•  You learned how to load a shared object on demand, preventing that some them be a burden at startup;•  You got some tips on how to write libraries to get the best performance;•  You understood that an UI that provides quick user feedback is more important than performance;
  49. 49. Q&A
  1. A particular slide catching your eye?

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

×