AVR-GCC i kolejny glupi problem z niechciana konwersja

Apr 09, 2004 21 Replies

Witam! Parê dni temu mia³em g³upi problem z niechcian¹ (i niepotrzebn¹) konwersj¹ niejawn¹ w if-ie. Pomog³o wprowadzenie zmiennej tymczasowej. Teraz walczê z podobnym problemem w switch-u i nie pomaga zupe³nie nic... Instrukcja switch (zmienna) generuje mi kilkanaœcie porównañ szesnastobitowych (zmienna jest typu unsigned char, promuje j¹ do inta i zaczyna porównywaæ z kolejnymi wartoœciami przy case-ach). Drgawek dosta³em jak zobaczy³em kod assemblerowy (zmienna jest w rejestrze r24):


1145 028c 9927 clr r25 //promuje mi moja zmienna do inta
1146 028e 8530 cpi r24,5
1147 0290 9105 cpc r25,__zero_reg__ //sprawdza r25 z zerem (a dopiero co sam go wyzerowal)
1148 0292 09F4 brne .+2
1149 0294 65C0 rjmp .L77
1150 0296 8630 cpi r24,6
1151 0298 9105 cpc r25,__zero_reg__ //znowu sprawdza r25
1152 029a A4F4 brge .L88
1153 029c 8230 cpi r24,2
1154 029e 9105 cpc r25,__zero_reg__ //i znowu...
1155 02a0 09F4 brne .+2
1156 02a2 43C0 rjmp .L72
1157 02a4 8330 cpi r24,3
1158 02a6 9105 cpc r25,__zero_reg__ //i znowu...
1159 02a8 2CF4 brge .L89

i tak jeszcze wiele razy (tu jest tylko próbka twórczoœci kompilatora). Co ja mam z tym zrobiæ? Nie pomaga zupe³nie nic, ani dodatkowa jawna konwersja na unsigned char, ani zmienne tyczasowe... czy w tym kompilatorze w ogóle _da_siê_ zrobiæ switcha na oœmiu bitach?


Dnia pią 9. kwietnia 2004 20:50 Darek R. napisał(a):

ZTCW to nie da się. Należy case unikać i przejrzeć archiwum listy avr-gcc,

formatting link
gdzie OIDP problem się przewinął parę razy.

Pozdrawiam

Marcin Stanisz napisa³

Ale sobie kompilator wybra³em... Zawsze mnie uczyli ¿e switch jest bardziej efektywny niz kilka if-ów, a tu na odwrót. Pomijam ju¿ fakt, ¿e kompilator powinien t³umaczyæ switcha na jeden rozkaz IJMP (zapisuj±c sobie wcze¶niej w rejestrze Z adres case-a odpowiadaj±cy warunkowi w switchu) a nie na kilkadziesi±t porównañ z kolejnymi liczbami, ale jak ju¿ musi to niech to chocia¿ robi na zmiennych o¶miobitowych... Bêdê musia³ przez to spory kawa³ek kodu przepisaæ w assemblerze a tak mi siê nie chce... :)

No fakt. Dziwne swoja droga ze gcc nie optymalizuje ..

O, spowobow kompilacji switcha jest sporo, kompilator powinien dobrac odpowiedni..

A probowales case '\x03' ?

J.

Moze wymus switch ((unsigned char) xxx) {} ?

pozdr. LB

J.F. napisa³

Fakt. Ale jak mam kilkadziesi±t case-ów numerowanych kolejno, to jakby nie patrzeæ najbardziej optymalna by³aby tablica z adresami etykiet a potem skok po¶redni pod adres wskazywany przez odpowiednie miejsce w tabeli. Ok, rozumiem ¿e IJMP nie jest zaimplementowany we wszystkich AVR-ach (choæ akurat w moim jest), wiêc zgadzam siê ¿e kompilator mo¿e sobie zrobiæ kolejne porównania. Ale czemu na 16 bitach?

Próbowa³em - dalej porównuje 16 bit.

drozdu napisa³:

Próbowa³em - bez zmian. W³a¶nie to mnie dobi³o - rozumiem ¿e mo¿e _domy¶lnie_ konwertowaæ na 16 bit - ale czemu konwertuje jak ja mu jawnie tego zabraniam?

To bynajmniej w zaden sposob nie zabrania konwersji.

J.

No coz - zawsze podejrzewalem ze gcc wyrosly w zasadzie na 32 bitach moze niezbyt pasowac do 8 :-)

Jest tam jakis adres - pomecz tworcow.

J.

J.F napisa³:

No w³a¶ciwie nie - mówi tylko kompilatorowi ¿eby skonwertowa³ pó¼niej raz jeszcze na 8 bit - w sumie wychodzi na jedno. Tyle ze kompilator i tak to ignoruje...

W takim przypadku przeciez mozesz explicite zrobic tablice z adresami kilkudziesieciu funkcji i wywolywac je przez wskaznik czytany z tablicy. To nawet wygodniejsze rozwiazanie, niz rozwijac switch'a. A jak sie zrobi z tego kilkaset funkcji to latwiej bedzie calosc rozparcelowac na kilka oddzielnych plikow zrodlowych, niz trzymac tyle kodu w jednym (trudniej zapanowac nad 1 plikiem dlugosci 100 KB, niz 5 x 20 KB). Poza tym w wielu przypadkach duzo czytelniejsza jest tablica z nazwami funkcji (np. obslugiwanych komend czy stanow jakiegos automatu), niz taki wieeeeloliniowy switch.

Nie zabrania tylko wymusza (zwsze bedzie traktowany jako unsigned char czy nie ?), u mnie dziala ok. ale poczytaj sobie np: na temat opcji -mint8 cos tam chyba bylo na ten temat, moze to cos da... Bo dziwne mi sie to wydaje ze unsigned char jest 2 bajtowy u ciebie moze jeszcze cos takiego, a w zadnym wypadku przy takim zapisie nie powinno juz byc dwoch konwersji przy zutowaniu (char->int->char).

pozdr. LB

Adam Dybkowski napisa³:

No i tak w³a¶nie pewnie bêdê musia³ zrobiæ. Tyle ¿e pisz±c switch chcia³em zaprz±c kompilator ¿eby zrobi³ to za mnie ;)

drozdu napisa³:

Hmm. Jak± masz wersjê avr-gcc?

U¿ywaj±c -mint8 mogê zrobiæ ¿e wszystkie inty s± o¶miobitowe, ale tego nie chcê (w wielu miejscach programu korzystam z szesnastobitowego inta i nie mam ochoty teraz tego przerabiaæ).

Nie no, unsigned char jest o¶miobitowy. Tyle tylko ¿e jak wywo³ujê switcha to zmienna która jest w jego argumencie jest konwertowana na inta bez wzglêdu na jej typ.

To moj± jawn± konwersjê kompilator po prostu ignoruje, a raczej chyba robi j± wcze¶niej, o tak (char->char->int).

Dnia sob 10. kwietnia 2004 02:24 Darek R. napisał(a):

Jak to mówią... Darowanemu koniowi nie zagląda się w zęby ;-) Albo się przysiada fałdów i poprawia kod avr-gcc.

Pozdrawiam

Marcin Stanisz napisa³:

To prawda. To ¿e AVR-GCC jest darmowy jest tak du¿± zalet± ¿e przys³ania wszystkie wady ;)

Nie martw sie - ine kompilatory tez maja wady. Moze nawet ten sam problem ze switchem. Co wiecej - support cie zlekcewazy, bo przeciez dziala. A do gcc masz zrodla - mozesz poprawic :-))))

J.

J.F. napisa³:

Wiem. Z innymi kompilatorami na AVR nie mam wprawdzie do¶wiadczenia, ale np. na Keilu na '51 to parê razy równo siê przejecha³em. Kompilator to tylko narzêdzie które pisa³ inny cz³owiek, a nikt nie jest nieomylny. Poza tym nie da siê kompilatora idealnie zoptymalizowaæ bo ró¿ni uzytkownicy maj± ró¿ne potrzeby.

Tu po prostu pyta³em bo mia³em nadziejê ¿e wystarczy np. daæ gdzie¶ jawn± konwersjê albo w³±czyæ jak±¶ opcjê podczas kompilacji i problem sam zniknie. ;) Wiem, naiwny jestem.

Szybciej bêdzie mi wstawiæ rêcznie skok pod adres z tablicy. Albo zostawiê jak jest - zoptymalizujê kod gdzie indziej i te¿ bêdzie ;)))

A wlasnie - probowales dac opcje optymalizacji ? Powinno mu sie udac.

J.

J.F. napisa³:

Próbowa³em z ró¿nymi poziomami optymalizacji. Niestety bez zmian.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required