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

[Bascom AVR] Optymalizacja kodu dla Attiny2313

MES Mariusz 27 Lip 2011 22:10 3855 23
  • #1 9766258
    MES Mariusz
    Poziom 36  
    Witam.

    Niejednokrotnie zdarza się, że mam potrzebę oprogramować urządzenie z podstawką na Attiny2313. Niestety ma on tylko 2kB pamięci kodu programu, co przekłada się na to, że funkcjonalność programu trzeba niejednokrotnie ograniczyć do minimum (a szkoda).

    Czy znacie jakieś triki optymalizacyjne, znacząco minimalizujące objętość kodu wynikowego?

    Obsługując z Attiny2313 wyświetlacz LCD 16x2 najwięcej traci się na stringach zawierających komunikaty dla LCD. Ja tekst pakuję przeważnie do stałych, i później stałe wykorzystuję w wielu powtarzających się miejscach programu.

    Nieco pamięci daje się czasem zaoszczędzić stosując select case zamiast if (w przypadku wielu warunków).

    Czasem zachodzi potrzeba zastosowania wielu warunków połączonych spójnikiem or (tego nie wiem jak zrobić inaczej).

    Programy muszą być oczywiście maksymalnie "uprocedurowione", staram się nigdy nie pisać dwa razy tego samego kodu.

    Wydaje mi się, że osiągam zazwyczaj sporą optymalizację kodu, niemniej jednak być może są jeszcze jakieś istotne kwestie optymalizacyjne, jeśli chodzi o Bascom AVR, które warto byłoby zacząć stosować?

    Z góry dziękuję za podpowiedzi kolegów programistów mających większe doświadczenie z pracą w owym niedoskonałym środowisku.
  • #2 9766367
    LordBlick
    VIP Zasłużony dla elektroda
    MES Mariusz napisał:
    Wydaje mi się, że osiągam zazwyczaj sporą optymalizację kodu, niemniej jednak być może są jeszcze jakieś istotne kwestie optymalizacyjne, jeśli chodzi o Bascom AVR, które warto byłoby zacząć stosować?
    Oczywiście wstawki w asm... ;)
  • #4 9766514
    manekinen
    Poziom 29  
    Sam nieraz muszę walczyć o pojedyncze bajty i kombinuję jak się da ;)

    Np zamiana wygodnego For Next na Do Loop z ręcznie zwiększaną i sprawdzaną zmienną... daje mniejszy kod.

    Inny przykład, zamiast przekazywać wartość do funkcji za pomocą Byval, lepiej zadeklarować sobie jakąś zmienną globalną, ręcznie ją ustawić/przepisać, i wywołać samą funkcję.

    I tak jak piszesz, każdy powtarzający się kod przynajmniej trzy razy, lepiej dać jako podprogram i sobie do niego skakać.

    Ciężko tak cokolwiek powiedzieć, może pokaż taki przykładowy kod który się nie mieści :)

    Pamiętaj także że jeśli masz pełną wersję to zawsze możesz edytować biblioteki i wycinać niepotrzebny kod.
  • #5 9766603
    xury
    Specjalista automatyka domowa
    Mam pewien pomysł na optymalizację dużej ilości np danych tekstowych kosztem SRAMu
    Zamiast trzymać testy we flashu można by było je tworzyć z danych, a we flashu jedynie trzymać dane wszystkich liter i cyfr. Kiedy byłby potrzebny jakiś tekst byłby tworzony przy pomocy danych zapisanych w array.
    Jak myślicie dało by to jakiś efekt ?
  • Pomocny post
    #6 9766893
    kamyczek
    Poziom 38  
    xury napisał:
    Mam pewien pomysł na optymalizację dużej ilości np danych tekstowych kosztem SRAMu
    Zamiast trzymać testy we flashu można by było je tworzyć z danych, a we flashu jedynie trzymać dane wszystkich liter i cyfr. Kiedy byłby potrzebny jakiś tekst byłby tworzony przy pomocy danych zapisanych w array.
    Jak myślicie dało by to jakiś efekt ?


    Jeśli chcesz je trzymać w pamięci RAM ok tyle że trzeba je tam włożyć bo ram jest ulotny zatem musza być w innej pamięci i zostać załadowane przy starcie systemu .

    Pozostaje więc wykorzystanie sprzętowego spi lub i2c i dołożenie zewnętrznej pamięci eeprom o ile wewnętrzny jest zbyt mały dodatkowo attiny 4313 ma dwa razy większą pamięć flash 4kB
  • #8 9767172
    MES Mariusz
    Poziom 36  
    kamyczek napisał:
    Pozostaje więc wykorzystanie sprzętowego spi lub i2c i dołożenie zewnętrznej pamięci eeprom o ile wewnętrzny jest zbyt mały

    Ma to sens. Taki 24c256 za 3 zł (32kB) warto zastosować dla układu z LCD gdzie będzie trzeba zrealizować dużo komunikatów. W ten sposób łatwo też przygotować wersję językową (jeden eeprom dla PL, drugi dla ENG i odwoływanie się pod te same adresy komunikatów ale do kostki o adresie w zależności od wersji językowej).

    Trzebaby się ewentualnie zastanowić w jaki sposób zorganizować sobie miejsce w pamięci EEPROM na komunikaty różnej długości, i jak się po te komunikaty wygodnie odwoływać. Ewentualnie napisać procedurę (znów zajmie trochę flash-u) do wygodnej obsługi komunikatów w EEPROM.

    Albo umieszczać komunikaty w eeprom kolejno bajt po bajcie i zapisywać sobie adres bajtu, który rozpoczyna kolejny wyraz. Niech w tym bajcie zapisana jest informacja ile znaków ma komunikat. Następnie stworzyć sobie zmienną dim komunikat$ *16 as string i przed wyświetleniem napisu wczytać sobie do tej zmiennej tyle znaków ile zawiera komunikat.

    coś w stylu:

    read_eeprom  zwrocona_wartosc$, adres_komunikatu$
    liczba_znakow_komunikatu$ = zwrocona_wartosc$
    for licznik = 1 to liczba_znakow_komunikatu
     read_eeprom  zwrocona_wartosc$, adres_komunikatu$ + licznik
     komunikat$ = komunikat$ + zwrocona_wartosc$
    next licznik
    lcd komunikat$
    





    kamyczek napisał:
    dodatkowo attiny 4313 ma dwa razy większą pamięć flash 4kB

    To również jest świetna wiadomość :-) Nie znałem tego uP.
  • #9 9767406
    manekinen
    Poziom 29  
    Jak koń pod górę... Dodaj te 3zł do ceny t2313 i dodaj tą dip8 do obudowy t2313... i masz atmega8. Nie wspominam już o kodzie wyżej który przecież dochodzi do puli, no i kod obsługi I2C.
  • #10 9767542
    kamyczek
    Poziom 38  
    Zamiast 24c32 proponuję 25320 lub inne działające po SPI z rodziny 25XXX są znacznie szybsze a sam program obsługi w przypadku USI też będzie bardziej zwięzły . Co do asemblera ,który proponował ktoś w poprzednich postach to też jest sposób na zmniejszenie kodu ale wymaga jego dobrej znajomości . Poza tym należy możliwie dużo używać układów peryferyjnych liczników i innych bo ich obsługa zazwyczaj skraca kod . Można też użyć nowszego wyświetlacza ze sterownikiem pracującym po spi . Którego kod obsługi będzie znacznie bardziej zwięzły ...
  • #11 9768036
    MES Mariusz
    Poziom 36  
    manekinen napisał:
    Jak koń pod górę... Dodaj te 3zł do ceny t2313 i dodaj tą dip8 do obudowy t2313... i masz atmega8. Nie wspominam już o kodzie wyżej który przecież dochodzi do puli, no i kod obsługi I2C.

    W tym momencie myślałem nie tylko o małym Attiny2313 ale również o dużo większych. Jeśli robiłeś większe projekty to być może spotkałeś się z sytuacją, gdzie nawet Atmega32 zacznie robić się ciasna. Jak dla mnie trzymanie komunikatów w EEPROM jest ok, to rozwiązanie mi się podoba, szkoda, że wcześniej do głowy mi nie przyszło. Rozwiązanie ciekawe koncepcyjnie i wbrew pozorom może być całkiem wygodne.
  • #12 9768372
    tmf
    VIP Zasłużony dla elektroda
    Nie myl pojęć. Zupełnie czym innym jest problem małej pamięci w mikrokontrolerze, który ma 2kB FLASH, a zupełnie czym innym w mikrokontrolerze, który ma jej 32 kB. Pomysł z zewnętrzną pamięcią w przypadku 2313 jest zupełnie poroniony. W przypadku M32 też pewnie łatwiej i taniej przejść na M64, 128/256. Lecz w tym ostatnim przypadku, problem małej ilości pamięci jest zapewne związany ze specyfiką programu i jego szczególnymi wymogami, stąd też może być celowe użycie zewnętrznej, dużej pamięci FLASH lub wręcz karty pamięci.
    Natomiast zamiast bawić się w poronione optymalizacje, należy dobrze dobrać procesor do realizowanego projektu i problem zniknie.
  • #13 9768622
    kamyczek
    Poziom 38  
    Tak najlepiej wstawić tam M256 lub nawet XM384... Jak kolega ma gotową płytkę na 2313 najłatwiej mu zmienić na 4313 lub dolepić pamiątkę na kilku przewodach . Tendencja jaką obserwuje wśród programistów C polega na pakowaniu M8 do urządzeń , które można uruchomić na układach z rodziny ATTINY 4, 10 czy 13 . i to się nazywa optymalizacja braku wiedzy programisty ...
  • #14 9768665
    Konto nie istnieje
    Poziom 1  
  • #15 9768782
    tmf
    VIP Zasłużony dla elektroda
    kamyczek napisał:
    Tak najlepiej wstawić tam M256 lub nawet XM384... Jak kolega ma gotową płytkę na 2313 najłatwiej mu zmienić na 4313 lub dolepić pamiątkę na kilku przewodach . Tendencja jaką obserwuje wśród programistów C polega na pakowaniu M8 do urządzeń , które można uruchomić na układach z rodziny ATTINY 4, 10 czy 13 . i to się nazywa optymalizacja braku wiedzy programisty ...


    Tak, jeśli ktoś porównuje ATTiny 4, 10 do ATMega8 to istotnie ma brak wiedzy. Proszę, nie kompromituj się.
    Szczególnie proponuję podłączyć zewnętrzny FLASH pod ATTiny4.
  • #16 9769454
    manekinen
    Poziom 29  
    MES Mariusz napisał:
    W tym momencie myślałem nie tylko o małym Attiny2313 ale również o dużo większych. Jeśli robiłeś większe projekty to być może spotkałeś się z sytuacją, gdzie nawet Atmega32 zacznie robić się ciasna. Jak dla mnie trzymanie komunikatów w EEPROM jest ok, to rozwiązanie mi się podoba, szkoda, że wcześniej do głowy mi nie przyszło. Rozwiązanie ciekawe koncepcyjnie i wbrew pozorom może być całkiem wygodne.

    Jak temat wskazuje, myślałem że rozmawiamy cały czas o t2313 i wpychaniu kodu na siłę. Wiadomo, że lepiej dać większy procesor i się nie męczyć, ale takie optymalizacje moim zdaniem to BARDZO dobry nawyk :) Zachowując niektóre dobre przyzwyczajenia, dające po kilkanaście głupich bajtów, przy programie np. 32kB uzyskane miejsce będzie rzędu 4kB - a w to można pomieścić sporo dodatkowych rzeczy :)

    Ale podpinanie zewnętrznej pamięci do układu z 1 czy 2kB flash to niezbyt zdrowy pomysł :)

    Może niech autor pokaże taki chociaż PRZYKŁADOWY kod który się nie mieści w t2313 i będziemy kombinowali :) Bo chyba o to chodziło?
  • #17 9769508
    tmf
    VIP Zasłużony dla elektroda
    manekinen: trochę się z tobą nie zgodzę. Myślę, że to co piszesz wynika z przyzwyczajeń z Bascoma. Jednak w C takie ręczne optymalizacje są kontrowersyjne. Z prostego powodu - kompilator w zależności od opcji kompilacji, wersji, producenta generuje dla takiego samego fragmentu w C różny kod assemblerowy. W efekcie możesz się namęczyć zamieniając dla przykładu for na while, a np. gcc w wersji 4.5 zrobi to automatycznie, albo okaże się, że dla niego z kolei for jest optymalniej tłumaczone niż while. IMHO optymalizować warto algorytm, bo to zawsze daje efekty i nie należy popełniać głupich błędów pisząc zawiły kod, tam, gdzie można go uprościć. Natomiast generalnie należy wybierać odpowiedni procesor do zadania, zamiast tracić czas na różne sztuczki, jak zaoszczędzić 100 bajtów. Oczywiście są sytuacje, kiedy warto jednak kod upychać, ale w 99% nie dotyczą one hobbystów.
  • #18 9769738
    kamyczek
    Poziom 38  
    Każdy inaczej widzi optymalizację dla jednego to program w 2 godziny dla innego zamiast 8kB w C 4kB w asemblerze kosztem czasu który ,trzeba poświęcić na napisanie kodu . Kolega napisał program w Bascomie , czy to tak ciężko zrozumieć że łatwiej jest wstawić tam 4313 i dopiąć np 25320 . Pamiątkę sobie zmieni i ma inny język . Z optymalizacją w C jest tak że albo opóźnienia się zmieniają albo program nie działa jak powinien. Program napisany w asemblerze można optymalizować pod każdym kątem od wykorzystania pamięci po czas wykonania operacji poza tym w sofcie umieszczasz tylko to co wykonujesz . Problem w tym , że pisanie w C polega na szukaniu gotowych fragmentów kodu i lepieniu ich w całość . Przykład proszę sobie policzyć czas odświeżania wyświetlacza na ks 108 porównać to z biblioteką w C i zrozumieć że uniwersalne biblioteki są jak szampon z odżywką który ani nie myje ani nie odżywia ...
  • #19 9770010
    tmf
    VIP Zasłużony dla elektroda
    No oczywiście, że tak. Tylko warto spojrzeć na to z drugiej strony - po co mam liczyć czas odświeżania, albo ogólnie po co coś ma być napisane idealnie (w kontekście zajętości pamięci, czy szybkości)? Czasami oczywiście musi, wtedy robi się wstawkę w asm i po kłopocie. Ale w 99,9% nie musi, a wtedy takie optymalizacje to tylko strata czasu i energii. Więc na końcu trzeba sobie wyliczyć, co lepiej - zmienić procesor i zapłacić dodatkowo np. 4zł, ale nie mieć narzuconych ograniczeń i pozwolić sobie na luźniejsze pisanie, czy te 4zł przyoszczędzić kosztem np. 20 dodatkowych godzin na projekt, poświęconych na rozwiązanie problemu typu co zrobić, żeby wykroić 100 bajtów.
    Co do optymalizacji w C i tego, że potem program nie działa jak powinien, to możesz podać konkretny przykład? Bo to dosyć odważne stwierdzenie.
  • #20 9770061
    kamyczek
    Poziom 38  
    Przykład jest prosty jeśli piszemy program krytyczny pod katem czasowym każda optymalizacja zmieniająca kod asm zmienia czas wykonywania kodu. Wielokrotnie wynikiem włączenia optymalizacji jest błędne działanie programu. A te 4 PLN w przypadku 1 szt to pryszcz ale w przypadku 1000 szt to już kawałek grosza ...
  • #21 9770455
    manekinen
    Poziom 29  
    tmf - oczywiście, mój poprzedni post w 100% dotyczył bascoma. Przecież o nim temat prawda? :) Bascom tworzy strasznie nieoptymalny kod i warto już od początku pisać całość zakładając że się nie zmieści :) Jeśli sami nie zoptymalizujemy kodu to nikt, a tym bardziej kompilator, za nas tego nie zrobi. I w cale nie jest to szukanie jakichś sztuczek, wystarczy użyć innej funkcji albo część działania matematycznego wykonać na innej mniejszej zmiennej, i patrzeć jak kod maleje w oczach :) Mnie się jeszcze nie udało "dobrać procesora do zadania" i przeważnie muszę szukać oszczędności :( Z tąd takie może właśnie podejście ale uważam że w przypadku bascoma to jak najbardziej dobry nawyk.
    Pozdrawiam
  • #22 9770709
    tmf
    VIP Zasłużony dla elektroda
    manekinen: no tak, dlatego też napisałem, że tylko częściowo się z tobą nie zgadzam :)

    kamyczek: no i właśnie takie sekcje krytyczne są wskazaniem do użycia wstawki assemblerowej. Ale taka konieczność zachodzi rzadko, a co więcej 99% kodu może być napisana normalnie w C. Zresztą to świetnie widać na przykładzie różnych OSów, gdzie cąłość jest w C, a pewne sekcje (np. context switching) są pisane w asmie. W tej sytuacji błędne działanie kodu nie jest wynikiem optymalizacji tylko błędnego programu i nieznajomości działania kompilatora. Co do tych 4 PLN, to znasz hobbystę, który robi projekt w ilości 1000 sztuk?
  • #23 9770759
    kamyczek
    Poziom 38  
    Każda uniwersalna procedura nie będzie optymalna , bez względu czy ją napiszemy w C czy bascomie . Wadą języków wysokiego poziomu i gotowych bibliotek jest ich wielkość , bo uniwersalność stosowania ogranicza możliwość skracania kodu (czytaj optymalizacji)
    Stwierdzenie że bascom tworzy mało optymalny kod można zastosować też do C . Problem polega na tym że brak znajomości architektury AVR i asemblera ogranicza postrzeganie tych zagadnień w kontekście kodu napisanego w C . Długość kodu nie jest w większości przypadków krytyczna ze względu na tanie i pojemne AVR w przystępnych cenach jednak patrząc na układy zasilane z baterii krótki kod to oszczędność energii i długa praca . Mniejszy mikrokontroler pobiera mniej energii i też przyczynia się do oszczędności . Do tego szybszy kod może działać z tą samą prędkością przy niższym taktowaniu i to też oszczędność energii.
  • #24 9771053
    tmf
    VIP Zasłużony dla elektroda
    To co piszesz to truizmy. Swoją drogą obecnie nie do końca prawdziwe - bo np. gcc potrafi automatycznie tworzyć specjalizowane wersje funkcji dla określonych parametrów. Generalnie optymalizacja współczesnych kompilatorów jest na tyle duża, że trudno w większym projekcie im dorównać, pisząc w czystym asmie. Z drugiej strony tak jak pisałem, optymalny kod zazwyczaj nie jest potrzebny.
    Nawet np. w aplikacjach gdzie ważne jest zużycie energii, więcej się zyska dobierając odpowiedni procesor, niż optymalizując kod. Nawet wśród AVR różnice poboru energii sięgają kilkuset procent, do kilu tysięcy % w przypadku użycia wyspecjalizowanych do tego mikrokontrolerów. Co do kodu - w takich aplikacjach krytyczny jest mały fragment, a nie cały kod. Nawet przyjmując, że kod w C jest dwukrotnie wolniejszy niż w asm (chociaż taka generalizacja jest bez sensu), to nie przekłada się to istotnie na zużycie energii. Czym jest taka niewielka różnica, wobec kilku tysięcy % zależnych od doboru procesora i kilkunastu tys. % zależnych od odpowiedniego algorytmu.
REKLAMA