2011-01-23 12 views
18

My processor, mały 16-bitowy mikrokontroler bez FPU i całkowitej matematyki ma tylko podział 16/16 i podział 32/16, które obie przyjmują 18 cykli. W tej chwili używam bardzo powolnego rutynowego oprogramowania (~ 7500 cykli) do podziału 64/32. Czy istnieje sposób na wykorzystanie tych mechanizmów podziału do obliczenia podziału 64/32? Podobnie do tego, w jaki sposób używam mnożnika 16x16 i sumatora do obliczania mnożenia 32x32? Używam C, ale mogę pracować z ogólnym wyjaśnieniem, w jaki sposób można to zrobić ... Mam nadzieję, że uda mi się skierować < 200 cykli (jeśli to w ogóle możliwe).64/32-bitowy podział na procesor z 32/16-bitowym podziałem

+0

co to za język? W większości (jeśli nie wszystkich) języków, podwójne/pojedyncze działa z FPU i jest dość szybkie ... chyba że czegoś tu brakuje –

+0

metinks on mówi o podziałach całkowitych, nie zmiennoprzecinkowy podział –

+0

Czy mówimy o pewnych specyficznych język (C, asm)? Czy urządzenie ma FPU, czy działa tylko w rejestrach całkowitych? –

Odpowiedz

8

Zobacz "Hackers's Delight", dział multiword (strony 140-145).

Podstawową koncepcją (wracając do Knutha) jest myślenie o swoim problemie w kategoriach base-65536. Następnie masz problem z 4 cyfrowymi i dwucyfrowymi podziałami, z dywizją 2/1 jako prymitywny.

Kod C jest tutaj: http://www.hackersdelight.org/hdcodetxt/divmnu.c.txt

3

Moja kopia Knuth (The Art of Programowanie komputerowe) jest w pracy, więc nie mogę go sprawdzić do poniedziałku, ale to byłby mój pierwszy źródło. Ma całą sekcję arytmetyczną.


edytuj: twój wpis o "16/16 działach i dywizjach 32/16, które obie biorą 18 cykli." - dsPIC mają warunkową operację odejmowania w zespole. Rozważ użycie tego jako swojego prymitywu obliczeniowego.

Należy również zauważyć, że jeśli X = XH * 2 + XL D = SC * 2 + DL następnie, jeśli patrząc na

(P, P) = X/D gdzie X = P * D + R

gdzie Q = QH * 2 + QL R = RH * 2 + RL następnie

XH * 2 + XL = SC * QH * 2 + (DL * QH + SC * QL) * 2 + (DL * QL) + RH * 2 +

RL

Sugeruje (patrząc w warunkach, które są wysokie 32 bitów) i stosuje się następującą procedurę, w rodzaju długich podziału:

  1. (QH, R0) = XH/(DH + 1) -> XH = QH * (DH + 1) + R0 [32/16] podzielić
  2. R1 = X - (QH * 2) * D [wymaga 16 * 32 mnożenie, przesunięcie lewej przez 16, a 64-bitowe odejmowanie]
  3. obliczyć R1' = R1 - D * 2
  4. gdy R1' > = 0, dostosowanie QH w górę o 1, ustawionej R1 = R1' i etap goto 3
  5. (QL, R2) = (R1 >> 16)/(DH + 1) -> R1 = QL * (DH + 1) + R2 [dzielenie 32/16]
  6. R3 = R1 - (QL * D) [wymaga pomnożenia 16 * 32 i 48-bitowe odejmowanie]
  7. oblicz R3 = R3 - D
  8. gdy R3' > = 0, QL regulacji w górę o 1, ustawionej R3 = R3' i stopień goto 7

Twój 32-bitowy iloraz to para (QH, QL), a 32-bitowa reszta to R3.

(Przy założeniu, że iloraz jest nie większy niż 32-bitowe, co trzeba wiedzieć z wyprzedzeniem, można łatwo sprawdzić z wyprzedzeniem).

+0

Dzięki za ten algorytm. Będę musiał pomyśleć o tym, jak go wdrożyć w C. –

-1

mogę zaproponować jedynie dostaniem wynik przez kolejne odejmowanie i rejestracja wyniku wyniku.Próba podzielenia rejestru 64-bitowego na 2 lub 4 części i podzielenie ich osobno jest bez zmian, ponieważ podział liczb całkowitych wprowadza błąd.

+2

Zbyt wolno. Podział Schoolbook jest szybszy. – Joshua

1

punktem wyjścia byłoby: D. Knuth, Sztuka programowania Vol.2 sekcja 4.3.1 algorytm D

Ale przypuszczam, że może być konieczne w celu optymalizacji algorytmu.

1

Może chcesz przejrzeć Booth's Algorithm (http://www.scribd.com/doc/3132888/Booths-Algorithm-Multiplication-Division).

Część, której potrzebujesz, ma około 1/2 strony w dół.

Nie patrzyłem na to od mojej klasy VLSI, ale to może być twój najlepszy zakład, jeśli to możliwe, możesz to zrobić w zespole, aby zoptymalizować go tak bardzo, jak to możliwe, jeśli będziesz dzwonił często.

Zasadniczo obejmuje zmianę i dodanie lub odjęcie.

+0

??? Booth's Algorithm służy do mnożenia, czyż nie? –

+0

@Jason S - Jeśli spojrzysz na artykuł, możesz go również użyć do podziału. –

Powiązane problemy