Operace v FP a iterační algoritmy INP 2008 FIT VUT v Brně 1
Operace FP Číslo X s pohyblivou řádovou čárkou X = M X.B Ex zapíšeme jako dvojici (M X, E X ), kde mantisa M X je ve dvojkovém doplňkovém kódu, nebo v přímém kódu se znaménkem na n M bitech, exponent E X je v kódu s posunutím 2 n E-1 na n E bitech. Třetím definičním údajem je hodnota základu B. Základní aritmetické operace na dvojici čísel X, Y s pohyblivou čárkou jsou: X + Y = (M X.2 Ex - Ey + M Y ).2 Ey, kde E X E Y X - Y = (M X.2 Ex - Ey - M Y ).2 Ey, kde E X E Y X * Y = (M X.M Y ).2 X : Y = (M X : M Y ).2 Ex + Ey Ex - Ey 2
Požadované operace v pohyblivéčárce Z obecného zápisu je zřejmé, jaké operace jsou zapotřebí. Pro sčítání a odčítání: 1. Vypočte se v pevnéčárce rozdíl E X - E Y 2. Posune se M X o E X - E Y bitů (tj. doprava, pokud je E X E Y ) 3. Vypočte se v pevnéčárce M X.2 Ex - Ey +/- M Y Dále je zapotřebí provést normalizaci a zaokrouhlení výsledku V = (M V, E V ). Normalizovat výsledek znamená posouvat mantisu vlevo (vpravo) a podle toho zmenšovat (zvětšovat) exponent E V tak dlouho, až se do sledovaného bitu (v 0 nebo v 1 ) dostane 1. Sčítání exponentů se provádí v binární sčítačce s korekcí, nebo ve speciální sčítačce pro posunutý kód s šířkou n E bitů, sčítání mantis se provádí v binární sčítačce se šířkou n M + 2 bitů s doplněným záchytným klopným obvodem S. 3
Princip obvodové realizace sčítačky/odčítačky FP E X E Y M X M Y 1 S X S Y n = E X - E Y 3 2 Pokud E X E Y, potom X +/- Y = (M X.2 EX - EY +/- M Y ).2 EY M s menším E M s větším E 3 1 4 6 7 4 1 Obecný postup (nevíme, zda E X E Y ): Rozdíl exponentů, nastavení sign a n 8 2 Prohození mantis podle sign 3 Posuv mantisy o n bitů vpravo E X E Y 5 4 Sečtení/odečtení mantis podle Add/Sub D 5 Zjištění počtu nul D v horních bitech mantisy 6 7 E - D S V E V M V 6 7 8 Normalizace mantisy, detekce spec. případů Úprava exponentu podle D a sign Logika pro výpočet znaménka 4
M X M Y E X E Y Násobeníčísel s pohyblivou řádovou čárkou M V = M X * M Y E V = E X + E Y Testování speciálních případů hodnot M V : M V = 0 M V nenormalizovaná M V normalizovaná E V := 0 Posuv M V o 1 bit vlevo E V := E V - 1 X * Y = M X.M Y 2 Ex+Ey výsledek V = (M V, E V ) Zaokrouhlení Přeplnění? ne ano Posuv M V o 1 bit vpravo E V := E V + 1 Testování speciálních případů hodnot E V : E V > e E max V < e e <_ E min V <_ min e max Konec 5
Obvodová realizace operací v FP Pro operace s plovoucíčárkou prováděné v rámci uvedených algoritmů by bylo možno teoreticky použít sčítačku a násobičku ALU s pevnou čárkou. V praxi se to však takto nikdy neděje. Obvody aritmetiky s pohyblivou čárkou jsou konstruovány jako zcela nezávislá jednotka s vlastním řadičem. 6
Iterační algoritmy Děleníčísel s pohyblivou čárkou a celou řadu dalších operací je možné v jednotce FPU provádět iteračními algoritmy. Newtonův iterační algoritmus dělení Tento algoritmus je založen na iteračním hledání průsečíku funkce f(x) s osou x pomocí tečny v bodě x i. y f(x) x i x i+1 x 7
Newtonův algoritmus dělení (1) Na základě odhadu x i hledáme přesnější odhad x i+1 v bodě průsečíku tečny funkce f s osou x. Rovnice přímky procházející bodem f(x i ) je y - f(x i ) = f '(x i )(x - x i ) Pokládáme-li přímku za aproximaci funkce f(x), můžeme psát f(x i+1 ) - f(x i ) = f '(x i )( x i+1 - x i ) V průsečíku tečny s osou x je f(x i+1 ) = 0, takže odtud dostáváme iterační vzorec x i+1 = x i - f(x i )/f '(x i ) Tento iterační vzorec nyní použijeme pro případ dělení. Máme-li dělit číslem b, zvolíme funkci f(x) = 1/x - b, a hledáme bod průchodu této funkce osou x, tedy bod x, kde f(x) = 0, takže pak 1/x = b, resp. x = 1/b. Operaci děleníčíslem b pak nahradíme násobením číslem 1/b. Derivace f '(x) = -1/x 2, odtud x i+1 = x i - (1/ x i - b)/(-1/ x i2 ) = = x i + x i - bx i2 = x i (2 - bx i ) 8
Newtonův algoritmus dělení (2) Postup výpočtu a/b je následující: 1. Posune se b tak, aby padlo do intervalu (1, 2) a pomocí tabulky odhadů zvolíme první odhad x 0. 2. Provedeme krok iteračního výpočtu x i+1 = x i (2 - bx i ). Krok 2 opakujeme tak dlouho, až se dosáhne požadované přesnosti na p bitů, kdy je relativní chyba (x i - 1/b)/(1/b) = 2 -p. Počet správných (přesných) bitů se každým iteračním krokem zdvojnásobuje, tedy v následujícím kroku i+1 je relativní chyba ( x i+1-1/b)/ (1/b) = 2-2p 3. Výsledek n-té iterace x n vynásobíme číslem a, výsledek x n.a posuneme o odpovídající počet bitů podle kroku 1. 9
Newtonův algoritmus dělení - příklad Spočtěte binárně 1/b pro b = 20. (20) 10 = (10100) 2 x i+1 = x i (2 bx i ) řádovou čárku posuneme tak, aby b <1, 2), tedy: 10100 1.0100 (o 4 bity doleva) zvolíme např. x 0 = 1, potom: x 1 = x 0 (2 bx 0 ) = 1.(10 1,01) = 1.0,11 = 0,11 x 2 = 0,11(10 1,01.0,11) = 0,11(10 0,1111) = 0,11.1,0001= 0,110011 x 3 = 0,110011(10 1,01.0,110011) = 0,110011(10 0,11111111) = = 0,110011.1,00000001 = 0,11001100110011 atd. řádovou čárku posuneme o 4 bity doleva: 0,000011001100110011 Ověření správnosti: 1/20 = 0,05 a (0,000011001100110011) 2 = (0,051952362) 10 10
Newtonův algoritmus dělení v HW x i+1 = x i (2 bx i ) MUX - multiplexer REG_X registr x REG_MINUS_B registr -b MULT1 násobička (-b*xi) ADDER sčítačka (2,0+(-b)*xi) MULT2 - násobička (xi*(2,0+(-b)*xi)) FSM konečný automat (kontrolér) SCNT synchronní čítač 11
* Goldschmidtův algoritmus dělení (1) Tento algoritmus se objevil poprvé asi u procesoru TI 8847, a prosadil se jako spolehlivý algoritmus dělení i dalších výpočtů s kvadratickou konvergencí. Byl použit v sálovém počítači IBM System/360, model 91, v jednotce FPU systému S/390, a v celé řadě navazujících serverů IBM, např. v serveru G4 v r. 1997 a dalších. Princip: zlomek a/b se rozšiřuje činitelem r zvoleným tak, aby se součin ve jmenovateli blížil k 1, tedy r.b 1. Pak je r 1/b, a stačí vypočítat hodnotu součinu a.r. Rozšiřování zlomku: a 0 r 1 r... r i -1 b 0 r 1 r... r i -1 12
* Goldschmidtův algoritmus dělení (2) Nyní položíme x 0 = a, y 0 = b. V iterační podobě počítáme v každém kroku výrazy x i +1 = r i x i, y i +1 = r i y i, kde x i a y i je i-tá aproximace hodnoty čitatele a jmenovatele po řadě. Z toho vyplývá, že podíl x i /y i = x i +1 /y i +1 = konst. = a/b Když vybereme r i tak že y i 1, pak x i a/b, tedy x i se blíží k hledanému podílu. Pozn.: Stejný postup se dá použít k i výpočtu druhé odmocniny z a. Nechť x 0 = a, y 0 = a. V každém kroku vypočítáme x i+1 = r i2 x i, y i+1 = r i y i. Pak x i+1 /y i+12 = x i /y i2 = 1/a, takže když se r i vyberou tak, aby to vedlo na x i 1, pak y i a. Tato metoda se používá k výpočtu druhé odmocniny v TI 8847. 13
* Goldschmidtův algoritmus dělení (3) Jak zvolit r i? Víme, že x 0 = a, y 0 = b, x i +1 = r i x i a y i +1 = r i y i Předpokládejme, že se b blíží co nejvíce 1, ale je zatíženo chybou δ. Položme b = 1 -δa IδI < 1. Zvolíme, že rozšiřujícíčlen r 0 se rovná r 0 = 1 + δ ; protože y 0 = b = 1 -δ, tak y 1 = r 0 y 0 = (1 + δ) (1 -δ) = 1 δ 2 Opět položíme r 1 = 1 + δ 2, takže y 2 = r 1 y 1 = 1 δ 4 a tak dále. Protože je IδI < 1, y i 1. S tímto výběrem r i bude x i vypočítáno jako x i +1 = r i x i = (1 + δ 2i ) x i = [1 + (1 b) 2i ] x i, protože b = 1 -δ, odtud δ = 1 b, což dosadíme do předchozí rovnice x i +1 = a [1 + (1 b)] [1 + (1 b) 2 ] [1 + (1 b) 2i ] 14
* Goldschmidtův algoritmus dělení (upravený postup výpočtu pro rychlejší konvergenci) Postup výpočtu: 1. a i b se posune tak, aby b leželo v intervalu <1, 2) 2. Vybere se odhad b* 1/b (z tabulky) 3. Položíme x 0 = a b*, y 0 = b b* (tímto trikem se zrychlí konvergence, protože bb* 1) 4. Iteruj, dokud x i není dostatečně blízko a/b. Cyklus: r 2 y // aby platilo, že když je y i = 1 +δ i, pak r 1 -δ i y = yr // y i + 1 = y i r 1 -δ i 2 x = x r Konec cyklu. // x i+1 = x i r x y r x/y 0 9.00000000 1.50000000 0.50000000 6.00000000 1 4.5 0.75 1.25 2 5.625 0.9375 1.0625 3 5.9765625 0.99609375 1.00390625 4 5.99990845 0.99998474 1.00001526 5 6 1 1 6 6 1 1 15
Další funkce Zde platí, že postupy vhodné pro programovou implementaci, jako MacLaurinův rozvoj nebo Čebyševovy polynomy atd. nemusí být pro obvodovou realizaci optimální, a proto byla odvozena řada modifikovaných nebo nových algoritmů. Druhá odmocnina Klasický postup hledání druhé odmocniny čísla A > 0 je založen na řešení rovnice x 2 - A = 0. Aplikací Newtonovy iterační metody dostaneme x i+1 = 1/2 (A/x i +x i ) Volíme x 0 > 0 a po dostatečném počtu iterací dostaneme druhou odmocninu čísla A. Opět platí, že je-li i-tá iterace zatížena chybou d, tedy x i = A(1 + d) pak v i+1 kroku dostaneme hodnotu x i+1 = A(1 + d 2 /2(1+d)) Tedy každým krokem získáme dvojnásobný počet platných číslic. 16
Druhá odmocnina lépe Pro realizaci technickými prostředky je výhodnější hledat Newtonovou iterační metodou řešení rovnice 1/y 2 - A = 0 Získáme tak iterační vzorec pro Newton-Raphsonův algoritmus y i+1 = y i (3 - A. y i2 )/2 Volíme-li 0 < y 0 < (3/A), pak po dostatečném počtu iterací dostaneme hodnotu 1/ A na požadovaný počet míst. Druhou odmocninu pak dostaneme výpočtem A= A.(1/ A) (Druhou odmocninu lze počítat rovněž modifikovaným Goldschmidtovým algoritmem - TI 8847). Všeobecná zásada je najít co nejrychlejší algoritmy, založené pouze na operacích sčítání (odčítání), posuvů a případně i násobení. 17
CORDIC (1) Algoritmus CORDIC - Coordinate Rotational Digital Computer publikoval J. E. Volder v r. 1959. V poslední době se velmi rozšířil a byl značně modifikován pro další typy výpočtů. Jeho základní myšlenka umožňuje pomocí jednoho algoritmu počítat většinu matematických funkcí vyčíslováním funkce ve tvaru a ± b.2 -i tedy pomocí součtů, rozdílů a posunů. Mezi nejznámější aplikace patří použití CORDICU v kapesní kalkulačce HP 35, v koprocesorech Intel počínaje I 8087, pro číslicovou Fourierovu transformaci, číslicovou filtraci signálů apod. Metodu CORDIC můžeme označit za metodu skládání dílčích úhlů. 18
y y B y A Φ α ϕ r B CORDIC (2) x B x x A Obecně vyjádříme přechod od bodu A k bodu B: r x A y A A = r.cos ϕ = r.sin ϕ V algoritmu Cordic je důležitý úhel Ø např. jeho sinus a kosinus chceme vypočítat. Počáteční úhel ϕ je nastaven na nějakou konvenční hodnotu, např. 0. Přechod od ϕ k Ø se provádí v krocích přičítání a odečítáním vhodných úhlů. Pokud vhodně zvolíme tyto úhly, stačí k výpočtu pouze sčítání, odčítání a posuny. x B = r.cos (ϕ + α) = r.cos ϕ.cos α - r.sin ϕ.sin α (1) y B = r.sin (ϕ + α) = r.sin ϕ.cos α + r.cos ϕ.sin α (2) 19
CORDIC (3) Dosadíme-li za r do (1) r = x A /cos ϕ, r = y A /sin ϕ pořadě, a do (2) v opačném pořadí, dostaneme pro cos α 0 x B = cos α (x A - y A.tg α) y B = cos α (y A + x A.tg α) Zvolíme-li x A = 1, y A = 0 (tj. ϕ = 0) a pro dané α určíme x B, y B (tedy otočíme vektor o α), dostaneme x B = cos α, y B = sin α. Požadovaný úhel natočení můžeme složit z n úhlů s kladným i záporným znaménkem (viz obrázek), tedy z orientovaných úhlů α i '. y y 0 α 2 α 3 Pozn. α i je buď +α i nebo -α i. α 1 x 0 =K x 20
CORDIC (4) Výsledný úhel natočení α = α 1 '+ α 2 '+... α n ' Postup výpočtu je pak následující: položíme x 0 ' = x A, y 0 ' = y A a určíme x i ', y i ' postupně pro i = 1, 2...n. Dostáváme pak iterační vzorce x i ' = cos α i '.( x i-1 ' - y i-1 '. tg α i ') (3) y i ' = cos α i '.( y i-1 ' + x i-1 '. tg α i ') (4) Ve dvojkové soustavě volíme takové úhly α i ', že platí tg α i ' = ± 2 1-i. Tím se v rovnicích (3), (4) nahradí násobení posuvem o i - 1 bitů. Další zjednodušení provedeme odložením násobeníčíslem cos α i ' nakonec výpočtu, kdy výsledek vynásobíme číslem K = cos α 1. cos α 2... cos α n kde α i = α i ', protože platí cos α i ' = cos α i '. Pro i = 1, 2,... n sestavíme tabulku hodnot α i, pro něž α i = arctg 2 1-i 21
Tabulka úhlů CORDIC Tato tabulka se uloží do permanentní pamětí ROM. i α tg α cos α 0 45 1 0,707 1 26,56 0,5 0,894 2 14,04 0,25 0,970 3 7,12 0,125 0,997 4 3,57 0,0625 0,998 5 1,789 0,03125 0,999 6 0,895 0,015625 0,9998 7 0,4476 0,0078125 0,9999 8 0,2238 0,0039063 0,99999 9 0,1119 0,0019531 0,999998 22
CORDIC (5) Pro x 0 = 1, y 0 = 0 tak dostaneme pro i = 1, 2,...n konečný tvar iteračních vzorců x i = x i-1 - y i-1. 2 1-i (5) y i = y i-1 + x i-1. 2 1-i (6) Tyto vzorce platí, pokud bereme α i z tabulky s kladným znaménkem. Pokud má α i záporné znaménko, prohodíme v (5) a (6) operace plus a mínus. Pak cos α = K.x n, sin α = K.y n. Položíme-li x 0 = K, y 0 = 0, vyhneme se násobení a výsledek je x n = cos α, y n = sin α. Pro úhly větší než 90 využíváme symetrie a opakování grafu goniometrických funkcí. Příklad: viz cvičení 23
int iterations; // počet iterací CORDIC v jazyce C http://en.wikipedia.org/wiki/cordic float arctantable[iterations]; // tabulka úhlů v radiánech float K = 0.6073; // K float v_x=1,v_y=0; // složky vektoru v for(int i=0; i < iterations; i++) { // vytvoření tabulky arctantable[i] = atan(pow(2,-i)); } y=sin(α) α x=cos(α) Vstupní úhel je α (v radiánech). Začíná se s vektorem v = (1,0). // vlastní algoritmus Cordic for(i = 0; i < iterations; i++) { // pokud je α záporné, přičteme úhel z tabulky: if( α < 0) { v_x = v_x + v_y*pow(2,-i); v_y = v_y - v_x*pow(2,-i); α += arctantable[i]; } // pokud je α kladné, odečteme úhel z tabulky else { v_x = v_x - v_y*pow(2,-i); v_y = v_y + v_x*pow(2,-i); α -= arctantable[i]; } } v_x *= K; v_y *= K; 24
CORDIC příklad výpočtu programu: Alfa = 0.523599 (rad) = 30.000001 (deg) Iteraci = 20, X = 1, Y = 0 Krok 0, Alfa = -0.261799, X = 1.000000, Y = 1.000000 Krok 1, Alfa = 0.201848, X = 1.500000, Y = 0.500000 Krok 2, Alfa = -0.043130, X = 1.375000, Y = 0.875000 Krok 3, Alfa = 0.081225, X = 1.484375, Y = 0.703125 Krok 4, Alfa = 0.018806, X = 1.440430, Y = 0.795898 Krok 5, Alfa = -0.012434, X = 1.415558, Y = 0.840912 Krok 6, Alfa = 0.003190, X = 1.428697, Y = 0.818794 Krok 7, Alfa = -0.004623, X = 1.422300, Y = 0.829955 Krok 8, Alfa = -0.000716, X = 1.425542, Y = 0.824400 Krok 9, Alfa = 0.001237, X = 1.427153, Y = 0.821615 Krok 10, Alfa = 0.000260, X = 1.426350, Y = 0.823009 Krok 11, Alfa = -0.000228, X = 1.425948, Y = 0.823705 Krok 12, Alfa = 0.000016, X = 1.426149, Y = 0.823357 Krok 13, Alfa = -0.000106, X = 1.426049, Y = 0.823531 Krok 14, Alfa = -0.000045, X = 1.426099, Y = 0.823444 Krok 15, Alfa = -0.000015, X = 1.426124, Y = 0.823401 Krok 16, Alfa = 0.000001, X = 1.426137, Y = 0.823379 Krok 17, Alfa = -0.000007, X = 1.426131, Y = 0.823390 Krok 18, Alfa = -0.000003, X = 1.426134, Y = 0.823385 Krok 19, Alfa = -0.000001, X = 1.426135, Y = 0.823382 X*K = 0.866092, Y*K = 0.500040 Výsledek cos(alfa) = 0.866092, sin(alfa) = 0.500040 Pozn.: 45 deg = 0,7854 rad a 26,56 deg = 0,4636 rad 25
CORDIC v HW (základní implementace) úhel v kroku i d i je znaménko úhlu 26
CORDIC další aplikace Metodu CORDIC lze použít též pro převod polárních souřadnic na pravoúhlé a naopak. Pro výpočet hodnot hyperbolických a hyperbolometrických funkcí byla vypracována modifikace algoritmu, kdy se koncový bod vektoru nepohybuje po kružnici, ale po hyperbole s rovnicí x 2 - y 2 = R 2. Pro výpočet hodnot logaritmických funkcí se pak použije vztahu ln w = 2.arctgh (w - 1)/(w + 1) pro w > 1, případně ln w = 2.arccotgh (w + 1)/(w - 1) pro w < 1. Pro výpočet exponenciálních funkcí se použije vztahů e w = cosh w + sinh w a w = e w.ln a Cyklometrické funkce vyčíslujeme opačným postupem. Hodnotu arctg y/x, tedy úhel α pro x > 0 můžeme určit postupným natáčením vektoru (x, y) až do polohy, kdy y = 0. Při skládání úhlu α postupujeme opět podle vzorců (5), (6). 27
Porovnáníčasové náročnosti instrukcí (Intel, od 486, 487) Počty taktů při provedení instrukcí (1) 28