-
Data: 2009-06-12 15:42:26
Temat: Re: Problem lekko OT, ale w WinAVR ;-)
Od: "T.M.F." <t...@n...mp.pl> szukaj wiadomości tego autora
[ pokaż wszystkie nagłówki ]W dniu 12.06.2009 03:54, Zbych pisze:
> T.M.F. pisze:
>
>> No zagladam dosyc czesto przy okazji debuggowania tego co napisalem.
>> Jakis koszmarnych brakow optymalizacji nie zauwazylem. Mozesz podac
>> konkretny przyklad w C, ktory jest zle optymalizowany? To zawsze mozna
>> zglosic jako bug.
>
> To zależy co kto uważa za koszmarne. Poniżej parę przykładów, ale
> wątpię, żeby komuś chciało się to czytać.
>
> Wszystkie przykłady były optymalizowane na rozmiar.
>
>
> ----------------------------------------------------
-----
> Testowanie warunków logicznych:
>
> #define PIN1_IS_LOW (!(PINB & (1<<PINB7)))
> #define PIN2_IS_LOW (!(PINB & (1<<PINB6)))
>
> volatile uint8_t a;
> asm volatile(";start");
> a = (PIN1_IS_LOW || PIN2_IS_LOW);
> asm volatile(";stop");
>
> Pomijając już tą nieszczęsną promocję do inta, to najbardziej w tym
> kodzie rozwaliło mnie wyłuskiwanie 6 bitu.
Promocja do int wynika ze standardu C wiec trudno tu robić zarzut
kompilatorowi. Żeby to ominąć wystarczy explicite typecastowac.
> Delikatna modyfikacja kodu:
>
> if (PIN1_IS_LOW || PIN2_IS_LOW) a = true;
> else a = false;
Tu faktycznie jest jakiś problem z optymalizacja. Warto to zgłosić jako Bug.
> ----------------------------------------------------
------
> Przygotowanie ramki na stosie dla 5 parametrów 16-bitowych:
>
> 1637 0068 ADB7 in r26,__SP_L__
> 1638 006a BEB7 in r27,__SP_H__
> 1639 006c 1A97 sbiw r26,10
> 1640 006e 0FB6 in __tmp_reg__,__SREG__
> 1641 0070 F894 cli
> 1642 0072 BEBF out __SP_H__,r27
> 1643 0074 0FBE out __SREG__,__tmp_reg__
> 1644 0076 ADBF out __SP_L__,r26
>
> Przy dwóch parametrach:
>
> 1751 010e 00D0 rcall .
> 1752 0110 00D0 rcall .
>
> Łatwo policzyć, że poniżej 8 parametrów bardziej opłaca się wersja z
> rcall (program optymalizowany na rozmiar).
Tu sprawa nie jest tak oczywista. Co prawda rcall są krótsze w sensie
długości kodu, ale zajmuja 3 takty zegara. To co generuje gcc zajmuje
niezależnie od długości ramki 9 taktow, czyli 3 rcall. Sytuacja wyglada
jeszcze gorzej kiedy PC jest 22 bitowy - wtedy 4 takty. Wiec jak sadze
wybrano pewien kompromis pomiedzy długością kodu a czasem egzekucji.
>
>
>
> ----------------------------------------------------
-------
> Adresowanie struktur i pobieranie adresów z flasha:
>
> typedef struct{
> const prog_char * a;
> const prog_char * b;
> const prog_char * c;
> const prog_char * d;
> }Aqq;
>
> prog_char s[] = "Aqq";
>
> Aqq PROGMEM tab[]={
> {s,s,s,s},
> {s,s,s,s},
> {s,s,s,s},
> {s,s,s,s},
> };
>
> asm volatile (";start");
> for (uint8_t i = 0; i < tab_size(tab); i++){
> blabla( pgm_read_word( &tab[i].a ), pgm_read_word( &tab[i].b ),
> pgm_read_word( &tab[i].c ), pgm_read_word( &tab[i].d ) );
> }
> asm volatile (";stop");
>
>
> Pierwszy problem to wyliczanie adresu w flashu:
To zalezy zapewne od zdefiniowanej przez ciebie funkcji tab_size(tab).
Kompilator za każdym obiegiem petli musi ja wywołać, żeby wilczyć wynik
dla danego argumentu - dlaczego? Bo ja źle zdefiniowałeś.
> Pomimo, że jest (czy raczej mogłoby być) użyte adresowanie z
> postinkrementacją, to adresy kolejnych elementów są i tak przed każdym
> pobraniem na nowo wyliczane. W przykładzie, który podałem daje to 12
> niepotrzebnych instrukcji w każdym obiegu tej krótkiej pętli i dodatkowo
> zajętą parę rejestrów R19:R18.
>
> Drugi problem, to wyliczanie od początku adresu komórki w tablicy przy
> każdym obiegu pętli:
>
Sprawdziłem to u siebie i nic takiego się nie dzieje. Musiałem
zdefiniować dodatkowo dziwna funkcje Babla bo mi kompilator to
optymalizował i ją wywalał.
> Wystarczy prosty myk ze wskaźnikiem i pętla się skraca:
>
> asm volatile (";start");
> for (uint8_t i = 0; i < tab_size(tab); i++){
> const Aqq * p = &tab[i];
> blabla( pgm_read_word( &p->a ), pgm_read_word( &p->b ), pgm_read_word(
> &p->c ), pgm_read_word( &p->d ) );
> }
Tu problem jest bardziej dyskretny. C przy adresowaniu elementów
struktury używa adresowania z przemieszczeniem. W pierwszym przykładzie
pobierasz adresy konkretnego elementu, stad za każdym razem są pobierane
pełne adresy. Za drugim razem używasz adresu struktury i offsetów do jej
elementów (operator -> generuje offsety). Zauważ, że gdyby pola tej
struktury były duże - powyżej 127 bajtów, to i tak zaszłaby konieczność
pobrania pełnego adresu, bo offset byłby większy niż maksymalne
przemieszczenie. Oczywiście kompilator może sobie z tym poradzić,
niestety tu wychodzi jedna z wad gcc - jest to kompilator pod duże
procki, a AVR jest tylko specyficzną wspieraną platformą. Żeby ta
optymalizacja dobrze zadziałała trzebaby nieźle zamieszać w kodzie gcc.
A w sumie jeśli często się ogląda sesje typu połączony C+assembler to
człowiek szybko się uczy jaka składnia języka jest optymalna. Akurat
przy pętlach ze względu na specyfikę listy rozkazów AVR można się nieźle
wykazać.
> A podobno gcc ma super optymalizator do pętli (widocznie moja wersja
> gdzieś go zgubiła).
Jak ci nie pasuje gcc to zaproponuj cos lepszego... nie mowiac juz o
tym, ze masz kod źródłowy wiec możesz się wykazać dla potomności :)
--
Inteligentny dom - http://idom.wizzard.one.pl
http://idom.sourceforge.net/
Teraz takze forum dyskusyjne
Zobacz, wyslij uwagi, dolacz do projektu.
Następne wpisy z tego wątku
- 12.06.09 15:47 T.M.F.
- 12.06.09 10:29 Zbych
- 12.06.09 17:14 T.M.F.
- 12.06.09 11:27 Zbych
- 12.06.09 16:46 J.F.
- 12.06.09 20:15 Grzegorz Kurczyk
- 12.06.09 20:30 J.F.
- 12.06.09 20:30 Zbych
- 13.06.09 01:35 Grzegorz Kurczyk
- 13.06.09 06:43 Grzegorz Kurczyk
- 13.06.09 07:28 Zbych
- 13.06.09 07:44 J.F.
- 13.06.09 14:35 T.M.F.
- 13.06.09 14:36 T.M.F.
- 13.06.09 14:37 T.M.F.
Najnowsze wątki z tej grupy
- e-paper
- 60 mA dużo czy spoko?
- Dziwne zachowanie magistrali adresowej w 8085
- Współczesne mierniki zniekształceń nieliniowych THD audio, produkują jakieś?
- Jaki silikon lub może klej?
- Smar do video
- Litowe baterie AA Li/FeS2 a alkaliczne
- "ogrodowa linia napowietrzna"
- jaki zasilacz laboratoryjny
- jaki zasilacz laboratoryjny
- Puszka w ziemię
- T-1000 was here
- Ściąganie hasła frezem
- Koszyk okrągły, walec 3x AA, na duże paluszki R6
- Brak bolca ochronnego ładowarki oznacza pożar
Najnowsze wątki
- 2025-02-19 Lista afer
- 2025-02-19 Lista afer
- 2025-02-19 Lista afer PIS
- 2025-02-19 Ogrodzenie dla krów szkockich "Highland"
- 2025-02-19 Gdańsk => System Architect (background deweloperski w Java) <=
- 2025-02-19 Gdańsk => Solution Architect (Java background) <=
- 2025-02-19 Białystok => Data Engineer (Tech Leader) <=
- 2025-02-19 Kraków => Ekspert IT (obszar systemów sieciowych) <=
- 2025-02-19 Warszawa => Architekt rozwiązań (doświadczenie w obszarze Java, AWS
- 2025-02-19 Rzeszów => International Freight Forwarder <=
- 2025-02-19 Poznań => Konsultant wdrożeniowy Comarch XL/Optima (Księgowość i
- 2025-02-19 Chrzanów => Spedytor Międzynarodowy (handel ładunkami/prowadzenie f
- 2025-02-19 Bieruń => Regionalny Kierownik Sprzedaży (OZE) <=
- 2025-02-19 Nigdy
- 2025-02-19 Katowice => Key Account Manager (ERP) <=