2013-05-29 16 views
12

Istnieje _mm_div_ps dla dzielenia wartości zmiennoprzecinkowych, istnieje _mm_mullo_epi16 dla mnożenia liczb całkowitych. Ale czy istnieje coś na dzielenie całkowite (wartość 16 bitów)? Jak mogę przeprowadzić taki podział?SSE z podziałem całkowitym?

+0

mało ludzi potrzeba, więc ... –

+0

Nope nie istnieje. Prawdopodobnie jest to kombinacja niewystarczającej liczby osób, które jej potrzebują wraz z trudnością (i umowną przestrzenią) jednostki dzielącej liczby całkowite. – Mysticial

+0

Czy chcesz podzielić przez stałą lub zmienną? –

Odpowiedz

8

proszę zobaczyć vectorclass Agner mgła jest on realizowany szybki algorytm zrobić podział całkowitą z SSE/AVX dla 8-bitowych, 16-bitowych i 32-bitowych słów (ale nie 64-bitowa) http://www.agner.org/optimize/#vectorclass

Look w pliku vectori128.h dla kodu i opisu algoirthma jako dobrze napisanej instrukcji VectorClass.pdf

Oto fragment opisujący algorytm z jego instrukcji.

„podział Integer Brak instrukcji w instrukcji x86 ustawiony i jego rozszerzenia, które są przydatna dla podziału całkowitą wektorowych, a takie instrukcje byłoby dość powolny, jeśli istniał. Dlatego biblioteka klasy wektor używa Algorytm dla szybkiej liczby całkowitej Podział Podstawowa zasada tego algorytmu może być wyrażona w tym wzorze: a/b ≈ a * (2n/b) >> n Obliczenie odbywa się w następujący sposób: 1. znajdź odpowiedni wartość dla n 2. obliczyć 2n/b 3. obliczyć niezbędne korekty błędów zaokrąglania 4. zrobić multiplikację Włącz i zmień w prawo i zastosuj poprawki do zaokrąglania błędów

Ta formuła jest korzystna, jeśli wiele liczb jest dzielonych przez ten sam dzielnik b. Kroki 1, 2 i 3 należy wykonać tylko raz, podczas gdy krok 4 powtarza się dla każdej wartości dywidendy a. Szczegóły matematyczne są opisane w pliku vectori128.h. (Patrz także T. Granlund i PL Montgomery. Podział według niezmiennych liczb całkowitych Korzystanie mnożenie, Proceedings of the SIGPLAN "...

Edycja: w pobliżu koniec vectori128.h plików pokazuje jak zrobić krótki podział ze zmienna skalarna "Wyliczenie parametrów używanych do szybkiego podziału zajmuje więcej czasu niż w przypadku podziału . Dlatego korzystne jest wielokrotne używanie tego samego obiektu dzielnika . Na przykład, aby podzielić 80 liczb całkowitych bez znaku przez 10:

short x = 10; 
uint16_t dividends[80], quotients[80];   // numbers to work with 
Divisor_us div10(x);       // make divisor object for dividing by 10 
Vec8us temp;         // temporary vector 
for (int i = 0; i < 80; i += 8) {    // loop for 4 elements per iteration 
    temp.load(dividends+i);     // load 4 elements 
    temp /= div10;        // divide each element by 10 
    temp.store(quotients+i);     // store 4 elements 
} 

"

Edit: całkowita dzielenie przez wektor szorty

#include <stdio.h> 
#include "vectorclass.h" 

int main() {  
    short numa[] = {10, 20, 30, 40, 50, 60, 70, 80}; 
    short dena[] = {10, 20, 30, 40, 50, 60, 70, 80}; 

    Vec8s num = Vec8s().load(numa); 
    Vec8s den = Vec8s().load(dena); 

    Vec4f num_low = to_float(extend_low(num)); 
    Vec4f num_high = to_float(extend_high(num)); 
    Vec4f den_low = to_float(extend_low(den)); 
    Vec4f den_high = to_float(extend_high(den)); 

    Vec4f qf_low = num_low/den_low; 
    Vec4f qf_high = num_high/den_high; 
    Vec4i q_low = truncate_to_int(qf_low); 
    Vec4i q_high = truncate_to_int(qf_high); 

    Vec8s q = compress(q_low, q_high); 
    for(int i=0; i<8; i++) { 
     printf("%d ", q[i]); 
    } printf("\n"); 
} 
+1

To jest naprawdę przydatne tylko dla podziału przez stałą - OP powiedział, że chce dzielić przez zmienną, w takim przypadku myślę, że jedyną opcją to rozpakować, przekonwertować na float i zrobić podział w float. –

+0

@PaulR, dodałem zmianę w odpowiedzi na Twój komentarz. Pod koniec pliku vectori128.h podaje przykład jak robić podziały szortów ze zmiennymi. Nie przejrzałem szczegółów, ponieważ podział liczb całkowitych nie był jeszcze wąskim gardłem w moim kodzie (czas, w którym musiałem go użyć, zrobiłem to poprzez przesunięcie bitów w prawo, które jest bardzo szybkie). –

+0

@PaulR, więc przyjrzałem się temu dokładniej. Szybka metoda w klasie VectorClass działa tylko dla skalarów. W przypadku wektora/wektora liczby całkowitej, myślę, że masz rację. Jedynym rozwiązaniem, jeśli musisz zrobić wektor interagera/wektor, jest zamiana na zmienne, zrobienie podziału i konwersja z powrotem na szorty. Dodałem do tego edycję. Sądzę, że możesz również zapisać szorty do tablicy do podziału skalarnego, a następnie je również wczytać. –