RTV forum PL | NewsGroups PL

Dlaczego AVR-GCC generuje zbędne porównania w switch'u dla unsigned char?

AVR-GCC i kolejny glupi problem z niechciana konwersja

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Dlaczego AVR-GCC generuje zbędne porównania w switch'u dla unsigned char?

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 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?

--
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/

elektroda NewsGroups Forum Index - Elektronika Polska - Dlaczego AVR-GCC generuje zbędne porównania w switch'u dla unsigned char?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map