Aktyw Forum

Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.

Sprawdź punkty Zarejestruj się

Optymalizacja (zamiana) funkcji w C na asm

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:
Optymalizacja (zamiana) funkcji w C na asm

Postautor: Sławek5 » 22 wrz 2006, o 11:01

CZeść
Mam taką funkcę liczącą log2(x) napisaną w AVR-GCC

Kod: Zaznacz cały

uint8_t clz(uint64_t x) { uint8_t n=0; if(x == 0) /* To niekoniecznie, troche trwa takie sprawdzanie, ale zeby sie tego pozbyc trzeba by zmodyfikowac petle ponizej, zeby sie nie 'wysypaly' */ return 64; /* Najpierw po calym bajcie */ while((x & 0xff00000000000000ULL) == 0) { /* dopoki najstarszy bajt = 0 */ n += 8; /* dodac 8 zer do licznika */ x <<= 8; /* wartosc przesunac o 8 bitow w lewo */ } /* A teraz po jednym bicie */ while((x & 0x8000000000000000ULL) == 0) { /* dopoki najstarszy bajt = 0 */ n += 1; /* dodac 1 zero do licznika */ x <<= 1; /* wartosc przesunac o 1 bit w lewo */ } return n; }
Ale jest też do niej komentarz:
Nie radzę tego próbować. avr-gcc jest mało 'kumatym' kompilatorem i cos mi się zdaje, że nie poradzi sobie z optymalizacją.
To samo napisane w asm będzie bardzo szybkie
Czy możecie mi podpowiedzieć jak to zobić w asm.
Liczba na wejsciu jest tupu int16_t

A w pgóle to potzrzebne mi to jest poto aby zamienić zakres licz na wejsciu od 0 do 35314 do wartości z zakresu 0 do 64.

Awatar użytkownika
bis
-
-
Posty:134
Rejestracja:12 maja 2005, o 08:11
Lokalizacja:Warszawa

Re: Optymalizacja (zamiana) funkcji w C na asm

Postautor: bis » 22 wrz 2006, o 11:55

A w pgóle to potzrzebne mi to jest poto aby zamienić zakres licz na wejsciu od 0 do 35314 do wartości z zakresu 0 do 64.
Zauważ że ta funkcja jedynie zlicza ilość zer wiodących w liczbie 64 bitowej. w Twoim przypadku będzie zwracać liczby z zakresu od 49 do 64 (16 wartości). Aby to działało choć trochę tak jak potrzebujesz to musiał byś najpierw ją rozciągnąć do 64 bitów.

Jeżeli typ int16_t oznacza liczbę 16 bitową ze znakiem to liczba 35314 jest poza zakresem stosowalności tego typu. Sprawdź ile wynosi max( int16_t ).

bis

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 22 wrz 2006, o 12:18

TAk zgadza sie nie dodałem tago i nie napisałem. Bo jajpierw tą liczbę moją 16bitowa muszę zanmienić jakoś na 64 bitową. Tylko nie wiem jak to zrobić, czy można po prostu podnieśc ją do 4 potęgi?

Awatar użytkownika
bis
-
-
Posty:134
Rejestracja:12 maja 2005, o 08:11
Lokalizacja:Warszawa

Postautor: bis » 22 wrz 2006, o 13:04

Wszystko zależy od tego co naprawdę chcesz uzyskać. Potęgowanie, owszem, rozciągnie, ale nieliniowo. Zwłaszcza że pragniesz to potem logarytmować. Chyba właściwsze było by "rozciągniecie" liniowe. I szybsze. Czyli pomnożenie zmiennej przez współczynnik S, skalujący z jednego zakresu (0..35314) na zakres (0..max64bit). Czyli liczbę S = max64bit / 35314. Jeszcze zastanów sie nad dokładnym określeniem co chcesz naprawdę uzyskać. Gdzieś wspominałeś że ma to być wyswietlane w postaci kresek. Wtedy masz do czynienia z 65 przedziałami (dla 0 do 64 ). Aby ten ostatni (64) się zapalał, to pewnie byś chciał, nie wyłącznie dla wartości 35314, ale dla pewnego przedziału wartości zbliżonych do tej liczby.

bis

Wróć do „AVR/AVR32”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 2 gości