Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Computer ControlsComputer Controls
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Optymalizacja "kompresja" i przyspieszenie programów Arduino

02 Jan 2018 18:29 3813 58
  • #31
    tplewa
    Level 38  
    tmf wrote:
    tplewa wrote:
    Odniosłem się do tego tematu tylko ze względu na to że padło porównanie z XMega...


    Padło porónanie do XMEGA, ale mam wrażenie, że nie zrozumiałeś kontekstu. Przeczytaj prosze ponownie ten post.


    Ale zrozumiałem... Odniosłem to do wcześniejszego mojego wpisu że na stosunkowo prostych i wolnych prockach używanie jakiś warstw abstrakcji nie jest IMHO najsensowniejszym wyborem (zwłaszcza że im bardziej uniwersalna warstwa HAL tym trudniej ją optymalnie napisać). Nie ma co ich porównywać do XMega czy tam ARM-ów gdzie w wielu wypadkach możemy sobie na coś takiego pozwolić. To oczywiście z jakiś moich obserwacji gdzie widzę że dany projekt można by zrobić na jakimś ATTiny - a jest większy AVR w Arduino... Sensu specjalnie w tym nie widzę... ale jak wspomniałem to tylko moje osobiste odczucia.
  • Computer ControlsComputer Controls
  • #32
    grko
    Level 33  
    Tak w zasadzie to o czym jest ten temat? Bo chyba wszyscy się zgodzimy, że bezpośrednie operowanie na porcie zajmie mniej niż call z API Arduino. Kolejny przykłąd odnośnie delay vs _delay_ms. Nie poparty żadnym porządnym testem i analizą:
    1. Czy każdy call funkcji delay powiększa kod o 180 bajtów czy tylko pierwszy?
    2. Informacja o tym, że _delay_ms to jest funkcja inline oraz, że wielkość kodu zależy od tego jak wywoływana jest ta funkcja (właśnie ze względu na inline):
    - call _delay_ms(1) zajmuje mniej niż _delay_ms(1000)
    3. Analiza rozmiaru symboli pliku *.elf daje odpowiedz dlaczego akurat API GPIO zajmuje tyle ile zajmuje.
    4. Brak analizy kodu bilbioteki. Przecież to jest publicznie dostępne.
    5. Jaki wpływa ma użycie różnych ficzerów C++ na rozmiar kodu RAM.

    W zamian dostaliśmy parę sztuczek przydatnych przy implementacji programowego SPI, I2C czy jakiejś innej protezy programowej. Lub jak się skończy miejsce. Zadam pytanie po co? Jaki jest tego sens? Nie lepiej po prostu kupić płytkę z większą ilością pamięci/SPI/I2C itd. Zazwyczaj są to przecież projekty mało seryjne (w 90% przypadków jedna sztuka).
  • #33
    User removed account
    User removed account  
  • #34
    tplewa
    Level 38  
    Piotrus_999 wrote:
    Kolega @R-MIK odkrył prawdy absolutne:

    1. Użycie frameworka nie będzie tak małe i szybkie jak napisanie wszystkiego ręcznie.
    2. Jak się ma mały procesor to nie można zrobić tyle samo i tak samo jak mając wiekszy/szybszy/lepiej uposażony.


    +1000000 ;)

    A no święta prawda i też mnie ten temat dziwi. Jakie jest Arduino i jaki e są jego wady/zalety każdy bawiący się w programowanie dobrze wie. Jeden chce zrobić coś szybko i nie chce wnikać zbytnio w temat wybierze Arduino inny sam wybierze procek dobry do danego zadania i sobie go oprogramuje...
  • Computer ControlsComputer Controls
  • #35
    tzok
    Moderator of Cars
    R-MIK wrote:
    Naturalnie, dobrze napisana bibliotek będzie operować na rejestrach ale kiepska już nie.
    Dobrze napisana biblioteka dla Arduino nie będzie operować na rejestrach, bo wtedy działałaby tylko na jednym procesorze, a Arduino to nie tylko ATMega 328P (a dawniej ATMega8).

    grko wrote:
    Nie lepiej po prostu kupić płytkę z większą ilością pamięci/SPI/I2C itd. Zazwyczaj są to przecież projekty mało seryjne (w 90% przypadków jedna sztuka).
    Otóż to. Po co tracić czas na coś co już zostało zrobione. Jak się musisz bawić w jakieś optymalizacje przy małoseryjnym produkcie, czy wręcz jednostkowym urządzeniu to wydaj 20zł, na mocniejszy uK i użyj gotowej biblioteki. Twój czas kosztuje więcej niż koszt mocniejszego uK.
  • #36
    tronics
    Level 38  
    Quote:
    Będzie. Po prostu są one inne pliki źródłowe bibliotek dla każdej platformy

    To się kłóci z tym czemu arduino służy. Oczywiście, to co kolega opisał czyli "cores" jak najbardziej jest blisko sprzętu i korzysta z rejestrów. Ale jeśli ktoś udostępnia bibliotekę np. obsługi HD44780 na I2C (z ekspanderem) to ona nie korzysta z rejestrów I2C atmega328 w jednej wersji, a I2C SAMD21 w innej, wreszcie I2C w STM32F103 w kolejnej... a korzysta z Wire.h i przez to taka biblioteka będzie działać na każdym z w/w, bo różnice sprzętowe przykryte są przez jednakową funkcjonalność bazowych bibliotek. Co za tym idzie taka biblioteka może być napisana super duper optymalnie, a i tak może działać bardzo różnie w zależności od tego ile się traci wydajności na wysłaniu 1bajta w I2C na libsach arduino w zależności od konkretnego sprzętu. A tak jak z machaniem pinami pewien narzut jest. Jednocześnie biblioteki dodatkowe też są różnej jakości, właśnie przetestowałem napisaną całkiem przyzwoicie bibliotekę do obsługi czujników dallasa (ds1820, 18b20, 18s20), rzecz w tym, że choć wszystko jest jasne i czytelne, to samo użycie tej biblioteki dokłada kilka kB flasha. Takie koszty obliczeń na float.
  • #37
    User removed account
    User removed account  
  • #38
    ditomek
    Level 21  
    Tez zrobiłem mały eksperyment.
    Pusty szkic (puste sekcje void setup i loop) to 440 bajty.
    Ten sam szkic tylko z jedna komendą pinmode w sekcji setup to 558 bajtów.
    Waga pustego szkicu moim zdaniem bierze się z definicji timera dla funkcji millis().
    Poprawcie mnie jak się mylę.
    Pozdrawiam
  • #39
    User removed account
    User removed account  
  • #40
    tronics
    Level 38  
    Pusty projekt w AS7 dla mega8 z int main(void) to 62B. AVR-GCC z tego co pamiętam 4.9.cośtam, -std=gnu99 oraz -Os. Próbowałem z void main(void) ale w tym przypadku akurat żadnego skutku to nie odniosło (oprócz tego, że pojawiły się warningi). Nie wiem jak wymusić generowanie lss dla projektów arduino (bo mam dodatek do AS7 pozwalający takowe importować, ale mimo ustawień toolchain i tak lss się nie generuje).
  • #41
    grko
    Level 33  
    @R-MIK Wystarczy odpowiednio ustawić sobie flagi kompilatora i tego typu "mikrooptymalizacje" dzieją się same.
  • #42
    tronics
    Level 38  
    @grko - właśnie do mnie dotarły blue pill :) 128KB flash (tzn. oficjalnie 64, ale akurat mają w rzeczywistości 128KB) i 20KB RAM. Teraz z ciekawości wgrałem ST-Linkiem prosty blink ;)
    Code: c
    Log in, to see the code

    Sketch skompilowany domyślnymi opcjami (bodajże -Os i -std=gnu11/gnu++11 bez LTO)
    Cóż takiego ciekawego pojawiło się w okienku wynikowym?
    Quote:
    Szkic używa 13028 bajtów (19%) pamięci programu. Maksimum to 65536 bajtów.
    Zmienne globalne używają 2816 bajtów (13%) pamięci dynamicznej, pozostawiając 17664 bajtów dla zmiennych lokalnych. Maksimum to 20480 bajtów.

    Ja jestem w stanie zrozumieć narzut jakiś funkcji obejmujących np. komunikację, albo obsługę ekspanderów itp. Ale tutaj jakikolwiek powód takiego zachowania by nie był to tego nie zaakceptuję.
    BTW z LTO wygląda ledwie delikatnie lepiej:
    Quote:
    Szkic używa 11404 bajtów (17%) pamięci programu. Maksimum to 65536 bajtów.
    Zmienne globalne używają 2792 bajtów (13%) pamięci dynamicznej, pozostawiając 17688 bajtów dla zmiennych lokalnych. Maksimum to 20480 bajtów.

    Jak zatem kolego R-MIK widzisz na STM32 wygląda to jeszcze gorzej. Nie sprawdzałem SAMD, ale mam już niejako pewne przeczucie czemu stosują D21 z 256KB flash i 32KB RAM ;)

    Osobiście arduino używam w zasadzie wyłącznie ze względu na projekty korzystające z MySensors, ale jak tylko będę miał więcej czasu by zrobić compatibility layer w czymś normalnym to Arduino IDE mówię "papa".
  • #43
    User removed account
    User removed account  
  • #44
    BlueDraco
    MCUs specialist
    Ciekawe, co za "fachowiec inaczej" przetłumaczył komunikat "pamięci dynamicznej"... ;)
  • #45
    kijas1
    Level 12  
    R-MIK wrote:
    Mnie zastanawia na co idzie tyle RAM?

    Strzelam - rezerwacja stosu i sterty ;)
  • #46
    tronics
    Level 38  
    R-MIK wrote:
    Mnie zastanawia na co idzie tyle RAM?

    Prawdopodobnie na obsługę USB virtual COM. Ale i tak chyba za dużo. Zresztą dziwne, że się sam podłącza do sketcha, ale te płytki oryginalnie nie mają bootloadera, właśnie sprawdzałem "czystą" i jest nierozpoznane urządzenie. Po wgraniu blinka jest urządzenie COM3
  • #47
    grko
    Level 33  
    @tronics To może rozwikłamy tajemnicę?

    Sekcja .text:
    Code: bash
    Log in, to see the code


    Sekcja .data:
    Code: bash
    Log in, to see the code
  • #48
    tronics
    Level 38  
    Code: bash
    Log in, to see the code

    Oraz
    Code: bash
    Log in, to see the code


    Dodam, że po zmienieniu metody programowania na "serial" i ponownym skompilowaniu sketch zajmuje ~6KB FLASH i <2KB RAM co jest dla mnie ... nieco nielogiczne. Zarówno przy STM32Duino bootloader i ST-Link ma ponad 12KB Flash i >2KB RAM.
  • #49
    bialy
    Level 15  
    tronics wrote:
    Code: bash
    Log in, to see the code


    Dodam, że po zmienieniu metody programowania na "serial" i ponownym skompilowaniu sketch zajmuje ~6KB FLASH i <2KB RAM co jest dla mnie ... nieco nielogiczne. Zarówno przy STM32Duino bootloader i ST-Link ma ponad 12KB Flash i >2KB RAM.


    Oczywiście większość pamięć konsumuje USB natomiast dość łatwo to zoptymalizować.
    W przypadku np. samd21g18
    "pusty sketch" - 10064 bajtów (3%) pamięci programu.
    po optymalizacji - 4940 bajtów (1%) pamięci programu.

    Zmiany są bardzo proste:
    1. w pliku platform.txt np. usuwamy -DUSBCON, jest to miejsce w którym możemy zmieniać flagi kompilacji.
    2. w pliku cores/arduino/USB/USBDesc.h komentujemy CDC_ENABLED oraz PLUGGABLE_USB_ENABLED
    Można próbować dodawać lokalne odpowiedniki plików.

    Resztę kodu zapewne też można jeszcze zoptymalizować.
  • #50
    tronics
    Level 38  
    Quote:
    Resztę kodu zapewne też można jeszcze zoptymalizować.

    Szczerze? Moje podejście do kodu jest takie - jak coś jest nieużywane to nie powinno trafiać do flasha. Ergo dopóki nie użyłbym Serial.println() to obsługa serial przez USB nie powinna w ogóle trafić do mikrokontrolera, bo niby "z jakiej paki"? Wrzuciłem to jako ciekawostkę jak domyślnie (!!) arduino działa w połączeniu z inną rodziną. Tu kolega jeszcze dopisał dla SAMD21 - świetnie! To pokazuje jak się "uszczęśliwia na siłę". A modyfikowanie globalnie plików konfiguracyjnych to jest po prostu średniowiecze.
  • #51
    bialy
    Level 15  
    tronics wrote:
    Quote:
    Resztę kodu zapewne też można jeszcze zoptymalizować.

    Szczerze? Moje podejście do kodu jest takie - jak coś jest nieużywane to nie powinno trafiać do flasha. Ergo dopóki nie użyłbym Serial.println() to obsługa serial przez USB nie powinna w ogóle trafić do mikrokontrolera, bo niby "z jakiej paki"? Wrzuciłem to jako ciekawostkę jak domyślnie (!!) arduino działa w połączeniu z inną rodziną. Tu kolega jeszcze dopisał dla SAMD21 - świetnie! To pokazuje jak się "uszczęśliwia na siłę". A modyfikowanie globalnie plików konfiguracyjnych to jest po prostu średniowiecze.


    Szczerzę to nie rozumiem sedna problemu :) Arduino jest kierowane do sporej grupy odbiorców dla której rozmiar wynikowego programu NIE jest problemem. Ważne, że nie muszą nic konfigurować i wszystko działa, czego chcieć więcej :) .
  • #52
    User removed account
    User removed account  
  • #53
    bialy
    Level 15  
    R-MIK wrote:
    bialy wrote:
    Arduino jest kierowane do sporej grupy odbiorców dla której rozmiar wynikowego programu NIE jest problemem.

    Powiedz to osobie, której zabrakło 1k flash czy 100b ram w ArduinoUno.


    Śmiem twierdzić, że w większości przypadków to nadal nie jest problem. Rozwiązanie znajdzie na forum po zamieszczeniu kodów :)
  • #54
    bialy
    Level 15  
    Nie rozumiem czemu kolega jest taki zdziwiony, to, że inne fora (szczególnie zagraniczne) tak działają i pomagają to nie powód do demonizowania takiego czy innego rozwiązania problemu. Biznes Arduino tak działa, i nikt nie ma z tym najmniejszego problemu.
  • #55
    tplewa
    Level 38  
    R-MIK wrote:
    bialy wrote:
    Arduino jest kierowane do sporej grupy odbiorców dla której rozmiar wynikowego programu NIE jest problemem.

    Powiedz to osobie, której zabrakło 1k flash czy 100b ram w ArduinoUno.


    Ale ja nie wiem po co ta dyskusja. Arduino zostało stworzone do celów edukacyjnych i tutaj nie widzę problemów.

    Jak już wspomniałem trudno jest napisać uniwersalną i optymalną warstwę abstrakcji aby w każdych warunkach się sprawdzała. Takie rozwiązania to zawsze jakiś kompromis.

    Na chwile obecną ktoś usiłuje z platformy z założenia projektowanej do zastosowań amatorskich zrobić kij wie co.
  • #56
    User removed account
    User removed account  
  • #57
    tplewa
    Level 38  
    R-MIK wrote:
    tplewa wrote:
    Na chwile obecną ktoś usiłuje z platformy z założenia projektowanej do zastosowań amatorskich zrobić kij wie co.

    Niestety tak jest. To jakby ABS w samochodzie zrobić na stykówce.


    Bardziej jak wymaganie od Fiata 126p aby jeździło się nim jak Ferrari Enzo  :)
  • #58
    ditomek
    Level 21  
    Arduino nie uczy wszystkiego, ale jednak uczy. I to z o wiele lepszymi efektami niż kiedyś Bascom.
    Gdyby nie było Arduino każdy ciągnął by dalej łacha z Bascoma ( bo z czegoś trzeba) i narzekał, że nie ma lepszej platformy dla początkujących. Jak taka się pojawia to spotyka się z krytyką.
    Może jedyne czego brakuje w Arduino to opcja "Expert" po jej wybraniu sam musisz o wszystkim pamiętać i zaawansowani programiści będą mieli gęby zamknięte bo zostają shieldy i cały hardware bez zmian a programowanie jest zdecydowanie trudniejsze.
    Tylko z drugiej strony po co? Przecież zawodowcy maja swoje platformy i rozwiązania. W takim razie czego się czepiać?
    To tak jak właściciel prawdziwego samochodu czepia się dziecka że bawi się samochodzikiem zabawką...
  • #59
    User removed account
    User removed account