Darek R.
Guest
Fri Apr 09, 2004 5:50 pm
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 kilkanacie porównań szesnastobitowych (zmienna jest
typu unsigned char, promuje jš do inta i zaczyna porównywać z kolejnymi
wartociami 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órczoci 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 omiu bitach?
--
Pozdrowienia
Dariusz Rzońca
Marcin Stanisz
Guest
Fri Apr 09, 2004 6:36 pm
Dnia pią 9. kwietnia 2004 20:50 Darek R. napisał(a):
Quote:
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).
ZTCW to nie da się. Należy case unikać i przejrzeć archiwum listy avr-gcc,
(http://www.avr1.org/mailman/listinfo/avr-gcc-list/) gdzie OIDP problem się
przewinął parę razy.
Pozdrawiam
--
Marcin Stanisz
"A lie will go round the world before the truth has got its boots on"
Terry Pratchett, "Truth"
Darek R.
Guest
Fri Apr 09, 2004 11:24 pm
Marcin Stanisz napisał
Quote:
ZTCW to nie da się. Należy case unikać i przejrzeć archiwum listy avr-gcc,
(http://www.avr1.org/mailman/listinfo/avr-gcc-list/) gdzie OIDP problem
się
przewinął parę razy.
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... :)
--
Pozdrowienia
Dariusz Rzońca
J.F.
Guest
Sat Apr 10, 2004 12:31 am
On Sat, 10 Apr 2004 02:24:36 +0200, Darek R. wrote:
Quote:
Ale sobie kompilator wybrałem...
No fakt. Dziwne swoja droga ze gcc nie optymalizuje ..
Quote:
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
O, spowobow kompilacji switcha jest sporo, kompilator powinien dobrac
odpowiedni..
Quote:
ale jak już musi to niech to chociaż robi na zmiennych ośmiobitowych..
A probowales case '\x03' ?
J.
drozdu
Guest
Sat Apr 10, 2004 8:02 am
Moze wymus switch ((unsigned char) xxx) {} ?
pozdr.
LB
Darek R.
Guest
Sat Apr 10, 2004 11:12 am
J.F. napisał
Quote:
O, spowobow kompilacji switcha jest sporo, kompilator powinien dobrac
odpowiedni..
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?
Quote:
ale jak już musi to niech to chociaż robi na zmiennych ośmiobitowych..
A probowales case '\x03' ?
Próbowałem - dalej porównuje 16 bit.
--
Pozdrowienia
Dariusz Rzońca
Darek R.
Guest
Sat Apr 10, 2004 11:13 am
drozdu napisał:
Quote:
Moze wymus switch ((unsigned char) xxx) {} ?
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?
--
Pozdrowienia
Dariusz Rzońca
J.F.
Guest
Sat Apr 10, 2004 12:21 pm
On Sat, 10 Apr 2004 14:13:57 +0200, Darek R. wrote:
Quote:
drozdu napisał:
Moze wymus switch ((unsigned char) xxx) {} ?
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.
J.F.
Guest
Sat Apr 10, 2004 12:21 pm
On Sat, 10 Apr 2004 14:12:43 +0200, Darek R. wrote:
Quote:
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?
No coz - zawsze podejrzewalem ze gcc wyrosly w zasadzie na 32 bitach
moze niezbyt pasowac do 8 :-)
Jest tam jakis adres - pomecz tworcow.
J.
Darek R.
Guest
Sat Apr 10, 2004 1:35 pm
J.F napisał:
Quote:
switch ((unsigned char) xxx) {}
To bynajmniej w zaden sposob nie zabrania konwersji.
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...
--
Pozdrowienia
Dariusz Rzońca
Adam Dybkowski
Guest
Sat Apr 10, 2004 9:09 pm
Darek R. wrote:
Quote:
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
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.
--
Adam Dybkowski
adybkows@amwaw.edu.pl
http://www.amwaw.edu.pl/~adybkows/