Zapomniana arytmetyka stałoprzecinkowa

Pisząc OpenFire potrzebowałem robić dużo operacji na liczbach z miejscami dziesiętnymi. Jako, że Amiga obsługuje floaty przez bibliotekę korzystającą z koprocesora albo emulacji programowej, postanowiłem pójść tą najbardziej oczywistą metodą. Niestety wydajność pozostawiała wiele do życzenia.

Generacja obróconych klatek pojazdów oparta o naiwną implementację macierzy rotacji na floatach, skutkowała wykonywaniem w UAE w trybie fastest possible w czasie 47s. Na cycle-exact A500 nie ważyłem się tego nawet odpalać. Po przejściu na fixed pointy czas zmalał do 13s.

Jak zatem działają fixed pointy? Otóż, tak jak w przypadku inta, liczba dalej reprezentowana jest jako kolejne potęgi dwójki, jednak część bitów przeznaczona jest na potęgi dodatnie, a część na ujemne. Te ostatnie tworzą miejsce po przecinku ze z góry określoną, stałą precyzją. W efekcie dodawanie dwóch liczb stałoprzecinkowych wykonuje się zwykłą operacją dodawania liczby całkowitej, oszczędzając przy tym shitload czasu w porównaniu z floatami. Dzielenie i mnożenie jest równie proste, lecz po operacji należy dokonać przesunięcia bitowego, odzwierciedlając tym samym przesunięcie przecinka, tak jak w mnożeniu lub dzieleniu pisemnym. Jako, że wynalazek ten jest stary jak świat, istnieją już do tego gotowce. Biblioteka libfixmath udostępnia: konwersję z i do typu stałoprzecinkowego, podstawowe operacje na tych liczbach, a także generatory funkcji trygonometrycznych, eksponenty, logarytmu a nawet pierwiastka kwadratowego.

Sama integracja biblioteki jest dość prosta – sprowadza się do jednego inkluda i skorzystania z dołączonego makefile’a lub dopięcia plików .c do głównego make’a projektu. Dodatkowo, biblioteka posiada szereg define’ów pozwalających na lepsze dopasowanie biblioteki do platformy sprzętowej, pozwalając na lepsze dopasowanie do platformy 32- lub nawet 8-bitowej. Ich dokładny opis znajduje się na wiki repozytorium

Choć wzrost wydajności jest kuszący, nie dostaje się go za darmo. Fiksy cechują się dużo mniejszą dokładnością obliczeń niż floaty, co bardzo było widać w “drżącej” grafice 3D na pierwszym PlayStation. Dodatkowo, pisząc w C, składnia staje się obrzydliwa z powodu braku przeładowania operatorów.

This entry was posted in Amiga and tagged , , , . Bookmark the permalink.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

This site uses Akismet to reduce spam. Learn how your comment data is processed.