logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[AVR][C] - pytanko do speców od C, kompilacja dla m8 i m168

mirekk36 12 Wrz 2009 17:44 1362 14
  • #1 7009900
    mirekk36
    Poziom 42  
    Witam,

    tak się zastanawiam - może mi ktoś podpowie dlaczego mam taki dziwny jak na razie dla mnie efekt, że ten samiuśki program , który napisałem dotąd na ATmega8 i zajmuje już prawie całą pamięć flash bo 95% czyli ok 7846 bajtów - po skompilowaniu dla procka ATmega168 - nagle zajmuje o nieco ponad 1kB !!!! więcej w pamięci flash ????

    zmiany, które musiałem wprowadzić ograniczone były tylko do nazw kilku rejestrów jak TCCR0 na TCCR0A i tym podobne. Rozumiem, że np ten nowszy procek ma nieco więcej wektorów przerwań i to już może zabiera nieco pamięci - ale żeby aż o 1kB???

    czy może ja coś źle robię - albo może powinienem na coś specjalnego zwracać uwagę w takich przypadkach???

    Pomijam oczywiście fakt - że sam kod można jeszcze nieco zoptymalizować - no ale tu dla porównania - kompilowałem identyczny kod
  • #2 7010296
    rusala
    Poziom 22  
    a na jakim poziomie optymalizacji to kompilujesz ?
  • #3 7010349
    mirekk36
    Poziom 42  
    do tej pory wszystko co kompiluję to na poziomie "-Os" - jak daję jakiekolwiek inne to zawsze kod puchnie jak dobre ciasto drożdżowe więc nie włączam tych innych optymalizacji - tym bardziej, że kod by się od razu nie zmieścił w m8
  • #4 7010359
    rusala
    Poziom 22  
    no to pozostaje Ci np. pokroic kod na kawalki i sprawdzic co sie powiekszylo i/lub zerknac w asemblera. Gdzies tu niedawno byl zreszta temat o tym jak sprawdzic ile co zajmuje.
  • #5 7010414
    mirekk36
    Poziom 42  
    niee - no taaak - tak sprawdzać to mogę - wystarczy zajrzeć w plik asemblerowy po kompilacji itp itp - znam te metody, ale ....

    .... ja mam od groma funkcji, procedur - no pisałem zapełnione prawie całe 8kB

    ..... dlatego pytam - czy może są jakieś ogólne inne przyczyny takiego zjawiska. Nawet jak znajdę jakąś funkcję czy kilka funkcji, które spuchły po przekompilowaniu na m168 - to i tak mi nie wyjaśni dlaczego kompilator to robi. Zestaw rozkazów w asemblrze jest praktycznie identyczny.

    Kiedyś jak pisałem bootloader to nawet nie dziwiło mnie i nie zastanawiało, że były takie różnice dla procka m8 i m32 - ale te różnice wtedy były kilkadziesiąt bajtów

    a tutaj ?
  • Pomocny post
    #6 7010462
    Mat_91
    Poziom 25  
    markosik20 napisał:
    W miarę "rozrastania" się programu kompilator inaczej sobie go optymalizuje. Mnie się zdarza czasami że mam np: 11kB kodu , dopisuje dużą funkcję i kompilator robi z tego wszystkiego 10kB.

    Cytat pochodzi z tematu Link

    To chyba wyjaśnia twoje wątpliwości? Po prostu chyba kompilator uznał że skoro ma 16kB pamięci, a program zajmuje mniej niż 8kB, to przecież ma jeszcze drugie tyle wolnego, i nie warto sie wysilać przy optymalizacji. Jak rozwiniesz ten kod to rozmiar pewnie zmaleje.
  • Pomocny post
    #7 7010521
    OldSkull
    Poziom 28  
    Różnica pewnie w dużej części wynika z avr/io.h. Różne rejestry (ATmega 8 i 88 dadzą różne ilości "wsadu", różne rozmiary pamięci (168 i 88 różnią się tylko ilością pamięci, a 168 daje większy kod). A w przypadku optymalizacji dochodzą kwestie jej jakości. W końcu jeśli jest miejsce we flashu, można optymalizować pod kątem szybkości działania i możliwe, że to właśnie robi.
    Jest to trochę dziwne, dobrze że ktoś na to zwrócił uwagę, ale raczej trzeba sie z tym pogodzić.
  • #8 7010809
    mirekk36
    Poziom 42  
    ok - mam więc nadzieję, że w miarę zbliżania się do końca pamięci m168 - kompilator znowu pójdzie po rozum do głowy i zacznie kurczyć skompilowany kod ;)

    Dodano po 38 [minuty]:

    o właśnie zaobserwowałem bardzo ciekawe zjawisko w wykonaniu kompilatora. Otóż mam kodzie taką strukturę:

    typedef struct {
    	uint8_t id[8];
    	uint8_t can_read;
    	int8_t trend_ico;
    } sslot;


    i po kompilacji kod ma dokładnie 7114 bajtów.

    Dodałem w trakcie kolejne potrzebne pole o tak:

    o właśnie zaobserwowałem bardzo ciekawe zjawisko w wykonaniu kompilatora. Otóż mam kodzie taką strukturę:

    typedef struct {
    	uint8_t id[8];
    	uint8_t can_read;
    	int8_t trend_ico;
    	uint8_t alarm;
    } sslot;


    i teraz - wg mnie kod powinien się chyba co najmniej - nieco rozrosnąć ..... a tu proszę, po kompilacji jest dokładnie 7096 bajtów (czyli mniej) OK widać , że kompilator nie śpi i za każdym razem coś tam turbo-optymalizuje w jedną albo drugą stronę ;)
  • Pomocny post
    #9 7011186
    Dr.Vee
    VIP Zasłużony dla elektroda
    W przypadku avr-gcc nie liczyłbym na optymalizację pod kątem zmieszczenia się w zadanej ilości pamięci flash. Pamiętajmy, że kompilacja każdej jednostki translacji wykonywana jest osobno, a następnie linker łączy wszystkie pliki obiektowe do pliku wynikowego - w takim scenariuszu w jaki niby sposób kompilator miałby skorzystać z informacji o globalnym wykorzysztniu pamięci flash?

    Do sprawdzenia co i ile zajmuje w kodzie można wykorzystać polecenie avr-nm --size-sort --radix=d <plik_elf>

    Co do różnic w rozmiarze kodu, to zauważ, że m8 ma wszystkie rejestry I/O w przestrzeni IO (dostępne przez in/out), a m168 ma dużo rejestrów dostępnych jedynie przez przestrzeń RAM (dostęp przez lds/sts). Spodziewam się, że tutaj ginie większość z tego kilobajta kodu :)

    Pozdrawiam,
    Dr.Vee
  • #10 7011224
    rusala
    Poziom 22  
    zgadzam sie, kompilator nie przewiduje ile zajmie caly kod ani w tym przypadku nie kombinuje ze zwiekszeniem predkosci bo przeciez jest ustawiony na optymalizacje s czyli na rozmiar.
  • #11 7011225
    mirekk36
    Poziom 42  
    Dr.Vee napisał:
    Co do różnic w rozmiarze kodu, to zauważ, że m8 ma wszystkie rejestry I/O w przestrzeni IO (dostępne przez in/out), a m168 ma dużo rejestrów dostępnych jedynie przez przestrzeń RAM (dostęp przez lds/sts). Spodziewam się, że tutaj ginie większość z tego kilobajta kodu :)


    to tyż prawda, kiedyś w asm - musiałem nieźle kombinować żeby przenieść kod na podobnego typu nowszy procek ;) .... tu nie muszę sam kombinować - kompilator czuwa ;) .... i dobrze

    dzięki za info
  • Pomocny post
    #12 7011238
    tmf
    VIP Zasłużony dla elektroda
    A kolejny powod oprocz rozmieszczenia IO to niemoznosc uzycia RCALL, zamiast tego kompilator, zeby osiagnac wszystkie lokacje musi uzywac CALL, co jest 2x dluzsze - 1 slowo vs. 2 slowa. Jako ze program glownie sklada sie z wywolan podprogramow to moze go znacznie wydluzyc.
    BTW, gcc nie potrafi przeprowadzac optymalizacji typu - skoro mam jeszcze 8 kB wolnego to sobie cos mniej zoptymalizuje, za to bedzie szybsze. Co wiecej - gcc w ogole nie ma pojecia ile dany procek ma FLASH/SRAM, co powoduje, ze mozesz sobie na M8 skompilowac program, ktory da 100kB kodu. A ze go potem nie wczytasz to inna bajka.
  • #13 7011350
    mirekk36
    Poziom 42  
    tmf --> o ile z tym Call i Rcall trudno się niezgodzić, to ...

    .... jednak kompilator wie ile procek ma pamięci flash - bo jak przekroczy kod rozmiar tej pamięci to w zasadzie kończy się to jakąś serią długich warningów
  • #15 7011424
    rusala
    Poziom 22  
    no dokladnie, i jak kawalki razem przekraczaja rozmiar pamieci to kupa ale do tego momentu kompilatorowi to obojetne i nie zwraca na to uwagi podczas optymalizacji
REKLAMA