| Author |
Message
|
Marcin_xx1 Poziom 18

Joined: 19 Apr 2005 Posts: 555 Location: krosno
|
#1
18 Sep 2008 03:56 Re: AVR prośba o optymalizacje kodu |
|
|
|
Witam. Jak to napisać optymalniej bo w obecnym stanie zżera mi dużo pamięci
if(i+e*10+f*100>=j+k*10+l*100&&j+k*10+l*100!=0)
Dzieki.
Dodano po 2 [minuty]:
język C
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8683 Location: Szczecin
|
#2
18 Sep 2008 08:36 Re: AVR prośba o optymalizacje kodu |
|
|
|
Witam,
sorki, ale jak widzę tak napisany warunek, to od razu przypomina mi się pewien dowcip z jednej ze stron w necie:
źródło anegdoty: http://www.e-lab.de/
co w wolnym tłumaczeniu może brzmieć tak:
| Quote: |
Programowanie w C polega na pisaniu tak:
for(;P("\n").R-;P("|"))for(e=3DC;e-;P("_"+(*u++/8)%2))P("| "+(*u/4)%2);
oraz szukaniu błędów wskaźników aż do osiągnięcia sukcesu...... |
i tak właśnie twoja, linijka przypomina jako żywo tę właśnie anegdotę. Oczywiście w każdym języku można "tak się załatwić" a jasne i przejrzyste programowanie i cała sztuka nie polega na tym aby jak najwięcej zmieścić w jednej linii.
.... rozbij to wszystko przed swoim warunkiem if na mniejsze fragmenty obliczeń i porównaj tylko ich wyniki, dzięki czemu poza uzyskaniem dużo większej przejrzystości kodu zapewne osiągniesz szybciej zamierzony cel w tym optymalizację
pozdrawiam
|
|
| Back to top |
|
 |
Google

|
#
18 Sep 2008 08:36 |
|
|
|
|
|
| Back to top |
|
 |
bobbyAIR Poziom 15

Joined: 12 Dec 2005 Posts: 268 Location: Wrocek
|
#3
18 Sep 2008 11:02 Re: AVR prośba o optymalizacje kodu |
|
|
|
na początek wystarczy tak
| Code: |
if ( (a = j+k*10+l*100)!=0){
if ((i+e*10+f*100)>=a){
}
}
|
dalej można kombinować z upraszczaniem kolejnych operacji:
to jak sądzę liczba dziesiętna składana z cyfr. Więc warunek
| Code: |
( j+k*10+l*100)!=0)
|
mozna zastąpić
pomija to mnożenie.
Dalej idąc jeśli a>=b to ten warunek jest spełniony przy dowolnej podstawie systemu obliczeniowego. W niektorych systemach operacje są szybsze. Np przesuwanie bitowe.
| Code: |
(i+e*10+f*100>=j+k*10+l*100)
|
jest równoważne
| Code: |
(i|(e<<1)|(f<<2))>=(j|(k<<1)|(l<<2))
|
a raczej szybciej się policzy
|
|
| Back to top |
|
 |
serum Poziom 14

Joined: 25 Oct 2006 Posts: 190 Location: szczecin
|
#4
18 Sep 2008 11:04 Re: AVR prośba o optymalizacje kodu |
|
|
|
Czy to w ogóle działa? Ja użyłbym tu z 10 nawiasów aby nie pomylić priorytetów operatorów i do tego było by to bardziej przejrzyste. Jak za miesiąc sięgniesz do tego kodu to spędzisz ze 2h odszyfrowując co miałeś na myśli. Staraj się nie używać pojedynczych literek jako nazw zmiennych, używaj nazw opisowych. Możesz spróbować wyliczyć poszczególne części warunku wcześniej wprowadzając nowe zmienne, jak chcesz żeby się szybko liczyło to napisz wstawkę ASM. Właściwie to jak dużo Ci to pamięci zajmuje? Nie wierzę żeby to miało znaczący wpływ na zużycie pamięci.
| Quote: |
Dalej idąc jeśli a>=b to ten warunek jest spełniony przy dowolnej podstawie systemu obliczeniowego. W niektorych systemach operacje są szybsze. Np przesuwanie bitowe.
Kod:
(i+e*10+f*100>=j+k*10+l*100)
jest równoważne
Kod:
(i|(e<<1)|(f<<2))>=(j|(k<<1)|(l<<2))
a raczej szybciej się policzy |
Coś mi się to nie podoba, bo weź np. i=9, e=9, f=1 ,j=0, k=0, oraz l=2
liczby jakie to reprezentuje to 199 oraz 200
po Twoim przekształceniu mamy 31 oraz 8 z czego wynika że pierwsza liczba jest większa, a to nieprawda. Policz to jeszcze raz, może się mylę.
|
|
| Back to top |
|
 |
bobbyAIR Poziom 15

Joined: 12 Dec 2005 Posts: 268 Location: Wrocek
|
#5
18 Sep 2008 12:53 Re: AVR prośba o optymalizacje kodu |
|
|
|
masz rację, dochodzi tu jeszcze kwestia cyfr w obu systemach. Trzeba przesunąc się o conajmniej 4 bit (2^4 > 9). Moja pomyłka, powinno być:
| Code: |
(i|(e<<4)|(f<<8))>=(j|(k<<4)|(l<<8))
|
Jednak dalej twierdzę, że to policzy się trochę szybciej.
|
|
| Back to top |
|
 |
Google

|
#
18 Sep 2008 12:53 |
|
|
|
|
|
| Back to top |
|
 |
serum Poziom 14

Joined: 25 Oct 2006 Posts: 190 Location: szczecin
|
#6
18 Sep 2008 14:19 Re: AVR prośba o optymalizacje kodu |
|
|
|
Oczywiście że się policzy szybciej, bo przesunięcia bitowe uC wykonuje chyba w jednym cyklu o ile się nie mylę. Tylko że autor pisze coś o zajętości pamięci a nie o szybkości wykonywania więc myślę że jego problem leży gdzie inndziej niż w pokazanym kawałku kodu gdyż po skompilowaniu i optymalizacji przez kompilator kod nie powinien zajmować zbyt dużo miejsca.
|
|
| Back to top |
|
 |
Google

|
#
18 Sep 2008 14:19 |
|
|
|
|
|
| Back to top |
|
 |
BoskiDialer Poziom 22

Joined: 28 Nov 2003 Posts: 1533 Location: Żory
|
#7
18 Sep 2008 14:41 Re: AVR prośba o optymalizacje kodu |
|
|
|
Marcin_xx1: Optymalizacja nie polega na zamienieniu jednej linijki w inną od tak, ale na maksymalnym wykorzystaniu pewnych założeń, których nie przekazujemy jawnie kompilatorowi.
Dla przykładu jeśli założymy, że wszystkie zmienne przyjmują wartości od 0 do 9, to wszystkie warunki się upraszczają (można zwiększyć bazę z 10 do (np)16 co już poczynił bobbyAIR).
Żeby uprościć porównanie z zerem do trzech prostych porównań musi być założenie, że zmienne są nieujemne i że w wyrażeniu nie występuje (celowe) przepełnienie.
Bez tych założeń jedyna możliwa operacja to wyciągnięcie wyrażenia tak jak zrobił to bobbyAIR - chociaż i tutaj jest potrzebne założenie, że zmienne są w tym momencie stałe (nie są np rejestrami IO lub są zmiennymi lokalnymi).
Tak więc najpierw napisz jakie są założenia do tych zmiennych.
serum: Przesunięcie w jednym cyklu? Tylko przy przesuwaniu o jeden bit. Przesunięcie o 4 bity w dowolną stronę da się zrobić przy 2 cyklach przy założeniu, że wartość jest w górnym(r16-r31) rejestrze (swap/andi). O dwa bity to dwie instrukcje (proste połączenie pojedynczych przesunięć).
bobbyAIR: Przy zwiększeniu bazy do 16 będzie to policzone szybciej (zamiast mnożenia, przesunięcia), warto jednak się zastanowić nad zwiększeniem bazy do 256 - wtedy kompilator może uprościć kod do trzech porównań(z przeniesieniem tj cp+2*cpc) bajtów bez przesuwań, a wynik będzie ten sam.
|
|
| Back to top |
|
 |
Marcin_xx1 Poziom 18

Joined: 19 Apr 2005 Posts: 555 Location: krosno
|
#8
18 Sep 2008 14:44 Re: AVR prośba o optymalizacje kodu |
|
|
|
| serum wrote: |
| Oczywiście że się policzy szybciej, bo przesunięcia bitowe uC wykonuje chyba w jednym cyklu o ile się nie mylę. Tylko że autor pisze coś o zajętości pamięci a nie o szybkości wykonywania więc myślę że jego problem leży gdzie inndziej niż w pokazanym kawałku kodu gdyż po skompilowaniu i optymalizacji przez kompilator kod nie powinien zajmować zbyt dużo miejsca. |
Macie racje, chodzi mi o szybkość wykonywania nie o zajętość pamięci, dzięki za pomoc, pozdrawiam.
|
|
| Back to top |
|
 |
BoskiDialer Poziom 22

Joined: 28 Nov 2003 Posts: 1533 Location: Żory
|
#9
18 Sep 2008 14:48 Re: AVR prośba o optymalizacje kodu |
|
|
|
Dodam jeszcze, że porównanie trzech bajtów z zerem można zrealizować w dwóch cyklach tracąc jeden z rejestrów z wartością: można policzyć sumę logiczną ("or rA, rB" + "or rA, rC"), rA będzie równe zero tylko wtedy, gdy wszystkie wartości są równe zero, dodatkowego porównania wartości rA z zerem nie trzeba, flagi są ustawione - nie wiem czy kompilator zoptymalizował by to do tego samego stopnia.
|
|
| Back to top |
|
 |
Marcin_xx1 Poziom 18

Joined: 19 Apr 2005 Posts: 555 Location: krosno
|
#10
18 Sep 2008 23:38 Re: AVR prośba o optymalizacje kodu |
|
|
|
To jszcze raz ja , po tym co zaraz przedstawie zarzucicie mi może ze nie wyciągam wszystkich wniosków z Waszych cennych uwag, są to moje pierwsze kroki w programowaniu i proszę o wyrozumiałość.
Pin 2 portuB jst zadeklarowany nastepująco: DDRB |= _BV(2);
i,e,f to zmienne lokalne odpowiadajace za bajty wyluskiwane z tablicy jakie trafiaja na siedmiosegmentowy, wyswietlacz led z multiplksowaniem.
j,k,l - jest to programowana trzy cyfrowa liczba porównywana do aktualnego wskazania licznika
Zmieniłem poprzedni kod
| Code: |
if(i+e*10+f*100>=j+k*10+l*100&&j+k*10+l*100!=0){
PORTB |= _BV(2);
}else{PORTB &=~ _BV(2);}
//co skutkuje wylaczeniem leda w razie spelnienia warunku |
na następujący:
| Code: |
aa=i+e*10+f*100;
bb=j+k*10+l*100;
if(aa>=bb&&bb!=0){
PORTB |= _BV(2);}else{PORTB &=~ _BV(2);} |
w tej postaci działa identycznie jak w poprzedniej(tak samo zmula mi procka)
natomiast gdy:
| Code: |
aa=i+e*10+f*100;
bb=j+k*10+l*100;
if(aa>=bb&&bb!=0){;} |
- program jest owiele szybszy, po prostu widzę to po częstotliwosci multipleksowania która mam zrealizowana w oparciu o glówną pętle.
Dodano po 5 [godziny] 55 [minuty]:
Problem udalo mi sie częsciowo rozwiązać obliczając zmienną bb tylko raz.
dodaje aktualny kod ktory jest moim poligonem doświadczalnym http://www.nopaste.pl/6ew , docelowo ma postać z tego czegoś : licznik obrotów,prędkościomierz i kontomierz w oparciu o enkoder inkrementalny z miezerą podziałką 120 impulsow na obrót który tez gdzieś na boku powstaje ;)
|
|
| Back to top |
|
 |
serum Poziom 14

Joined: 25 Oct 2006 Posts: 190 Location: szczecin
|
#11
19 Sep 2008 23:59 Re: AVR prośba o optymalizacje kodu |
|
|
|
Pierwsze co mnie uderzyło w Twoim programie to deklaracje zmiennych w funkcji main, dlaczego wszystkie mają atrybut register ?? Niech mnie ktoś poprawi jeśli źle mówię, ale jeśli kilkanaście zmiennych ma atrybut register to kompilatorowi szybko zabraknie rejestrów do umieszczania tych zmiennych. Weź je zadeklaruj jako zwykłe zmienne.
Podziwiam Cię - 750 linijek kodu upchane w jednej funkcji main(), napracowałeś się, ale ja tego bym nie chciał analizować;]
|
|
| Back to top |
|
 |
Dr.Vee Poziom 22

Joined: 16 May 2008 Posts: 1808 Location: Wrocław
|
#12
20 Sep 2008 00:50 Re: AVR prośba o optymalizacje kodu |
|
|
|
| serum wrote: |
| Podziwiam Cię - 750 linijek kodu upchane w jednej funkcji main(), napracowałeś się, ale ja tego bym nie chciał analizować;] |
Boże, widzisz i nie grzmisz... :cry:
* Brak formatowania kodu
* Wszystkie nazwy zmiennych jedno bądź dwuliterowe
* Instrukcje skoku goto (!)
I jak tu się dziwić, że niektórzy nazywają C "wysokopoziomowym asemblerem"... Dawno takiego spaghetti nie widziałem :)
Myślę, że optymalizacja wyrażenia z pierwszego postu to był najmniejszy z Twoich problemów :D
Pozdrawiam,
Dr.Vee
|
|
| Back to top |
|
 |
Marcin_xx1 Poziom 18

Joined: 19 Apr 2005 Posts: 555 Location: krosno
|
|
| Back to top |
|
 |
Google

|
#
21 Sep 2008 01:46 |
|
|
|
|
|
| Back to top |
|
 |
Dr.Vee Poziom 22

Joined: 16 May 2008 Posts: 1808 Location: Wrocław
|
#14
21 Sep 2008 03:54 Re: AVR prośba o optymalizacje kodu |
|
|
|
No tak, jaki kod, taki prototyp - a może na odwrót? :)
|
|
| Back to top |
|
 |
serum Poziom 14

Joined: 25 Oct 2006 Posts: 190 Location: szczecin
|
#15
21 Sep 2008 17:06 Re: AVR prośba o optymalizacje kodu |
|
|
|
To nie chodzi o to czy działa, czy nie (chociaż lepiej jak działa). Program pisany w ten sposób jest niemodyfikowalny. Bardzo ciężko dodać do niego nowe funkcje lub wykorzystać funkcje z tego programu w jakimś innym programie. Dlatego powinieneś wziąć do serca rady moje i kolegów i zacząć pisać programy zgodnie ze sztuką programistyczną bo później będziesz płakał. Prototyp jak prototyp, też mi się zdarza robić prototypy gdzie więcej kabelków niż czego innego. Dlatego to się nazywa prototyp;]
|
|
| Back to top |
|
 |