Codesize-Profiler



  • Moin,

    ich suche ein Tool, mit dem man für jede einzelne Funktion eine Abschätzung erhält, wie viel Platz sie im Binary belegt.
    Man könnte da etwa den Assembleroutput des Compilers zur Hilfe nehmen - dabei sind zwar noch nicht Daten aus anderen Segmenten dabei, es wäre aber ein Anfang.
    Gibt es sowas schon? Es reicht schon, wenn es mit g++/Linux läuft.



  • Ich bin nicht sicher. Aber vielleicht reicht Dir

    #include <iostream>
    using namespace std;
    
    int foo(){
            char tmp[100];
            tmp[5]=17;
            return tmp[5];
    }
    
    int bar(int n){
            if(n==0)
                    return 1;
            else
                    return bar(n-1)+bar(n-1);
    }
    
    int main(){
            cout<<foo()<<' '<<bar(10)<<'\n';
            return 0;
    }
    
    $> g++ -c main.cpp
    
    $> nm -SC main.o
    
    00000101 0000001a t global constructors keyed to _Z3foov
    00000012 0000003e T bar(int)
    00000000 00000012 T foo()
    000000bf 00000042 t __static_initialization_and_destruction_0(int, int)
             U std::ostream::operator<<(int)
             U std::ios_base::Init::Init()
             U std::ios_base::Init::~Init()
             U std::cout
    00000000 00000001 b std::__ioinit
             U std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char)
             U __cxa_atexit
             U __dso_handle
             U __gxx_personality_v0
    00000050 0000006f T main
    
    $> g++ main.cpp
    
    $> nm -SC a.out
    
    08049f08 d _DYNAMIC
    08049ff4 d _GLOBAL_OFFSET_TABLE_
    08048751 0000001a t global constructors keyed to _Z3foov
    0804882c 00000004 R _IO_stdin_used
             w _Jv_RegisterClasses
    08048662 0000003e T bar(int)
    08048650 00000012 T foo()
    0804870f 00000042 t __static_initialization_and_destruction_0(int, int)
             U std::ostream::operator<<(int)@@GLIBCXX_3.4
             U std::ios_base::Init::Init()@@GLIBCXX_3.4
             U std::ios_base::Init::~Init()@@GLIBCXX_3.4
    0804a040 0000008c B std::cout@@GLIBCXX_3.4
    0804a0d4 00000001 b std::__ioinit
             U std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char)@@GLIBCXX_3.4
    08049f00 D __DTOR_END__
    0804a028 A __bss_start
             U __cxa_atexit@@GLIBC_2.1.3
    0804a020 D __data_start
    0804a024 D __dso_handle
             w __gmon_start__
             U __gxx_personality_v0@@CXXABI_1.3
    08049ef0 d __init_array_end
    08049ef0 d __init_array_start
    08048770 00000005 T __libc_csu_fini
    08048780 00000062 T __libc_csu_init
             U __libc_start_main@@GLIBC_2.0
    0804a028 A _edata
    0804a0d8 A _end
    0804880c T _fini
    08048828 00000004 R _fp_hw
    080484e4 T _init
    08048590 T _start
    0804a020 W data_start
    080486a0 0000006f T main
    
    $> g++ -O3 -march=native main.cpp
    
    $> nm -SC a.out
    
    08049f08 d _DYNAMIC
    08049ff4 d _GLOBAL_OFFSET_TABLE_
    0804869a 0000002c t global constructors keyed to _Z3foov
    08048a8c 00000004 R _IO_stdin_used
             w _Jv_RegisterClasses
    080486c6 0000015e T bar(int)
    08048690 0000000a T foo()
             U std::ostream::operator<<(int)@@GLIBCXX_3.4
             U std::ios_base::Init::Init()@@GLIBCXX_3.4
             U std::ios_base::Init::~Init()@@GLIBCXX_3.4
             U std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, int)@@GLIBCXX_3.4.9
    0804a040 0000008c B std::cout@@GLIBCXX_3.4
    0804a0d4 00000001 b std::__ioinit
    08049f00 D __DTOR_END__
    0804a028 A __bss_start
             U __cxa_atexit@@GLIBC_2.1.3
    0804a020 D __data_start
    0804a024 D __dso_handle
             w __gmon_start__
             U __gxx_personality_v0@@CXXABI_1.3
    08049ef0 d __init_array_end
    08049ef0 d __init_array_start
    080489d0 00000005 T __libc_csu_fini
    080489e0 00000062 T __libc_csu_init
             U __libc_start_main@@GLIBC_2.0
    0804a028 A _edata
    0804a0d8 A _end
    08048a6c T _fini
    08048a88 00000004 R _fp_hw
    0804851c T _init
    080485d0 T _start
    0804a020 W data_start
    08048824 000001ab T main
    

    Keine Ahnung, ob die angegebenen Größen glaubwürdig sind. Die würde ich erstmal mit dem assembler-Code vergleichen, den man mit --save-temps so fein kriegt.



  • Athar schrieb:

    Moin,

    ich suche ein Tool, mit dem man für jede einzelne Funktion eine Abschätzung erhält, wie viel Platz sie im Binary belegt.
    Man könnte da etwa den Assembleroutput des Compilers zur Hilfe nehmen - dabei sind zwar noch nicht Daten aus anderen Segmenten dabei, es wäre aber ein Anfang.
    Gibt es sowas schon? Es reicht schon, wenn es mit g++/Linux läuft.

    Das ist doch total hohl! Da man ja nach der compilierung nocht weiter gehen kann und nicht benötigte Methoden durch ein Tool wieder entfernen lassen kann. Das heißt schlussendlich were es nicht nur von dem abhängig, was du codest, sondern was eingebunden und aufgerufen wird.



  • Danke für den Tipp, nm scheint das Problem elegant lösen zu können. Die Größenangaben sind aber praktisch immer ein gutes Stück kleiner als der real für die Funktion generierte Assemblercode, mal sehen, was das für Zusammenhänge hat.

    Höherwertiges Wesen schrieb:

    Das ist doch total hohl! Da man ja nach der compilierung nocht weiter gehen kann und nicht benötigte Methoden durch ein Tool wieder entfernen lassen kann. Das heißt schlussendlich were es nicht nur von dem abhängig, was du codest, sondern was eingebunden und aufgerufen wird.

    Und worauf willst du hinaus?


Anmelden zum Antworten