Kilka razy spotkałem się z tym terminem w matlabie, fortranie ... innym ... ale nigdy nie znalazłem wyjaśnienia, co to znaczy i co robi? Pytam więc, czym jest wektoryzacja i co oznacza na przykład, że „pętla jest wektoryzowana”?
Kilka razy spotkałem się z tym terminem w matlabie, fortranie ... innym ... ale nigdy nie znalazłem wyjaśnienia, co to znaczy i co robi? Pytam więc, czym jest wektoryzacja i co oznacza na przykład, że „pętla jest wektoryzowana”?
Odpowiedzi:
Wiele procesorów ma zestawy instrukcji „wektorowe” lub „SIMD”, które stosują tę samą operację jednocześnie do dwóch, czterech lub więcej elementów danych. Nowoczesne układy x86 mają instrukcje SSE, wiele układów PPC ma instrukcje „Altivec”, a nawet niektóre układy ARM mają zestaw instrukcji wektorowych o nazwie NEON.
„Wektoryzacja” (uproszczona) to proces przepisywania pętli, tak aby zamiast przetwarzać pojedynczy element tablicy N razy, przetwarza (powiedzmy) 4 elementy tablicy N / 4 razy jednocześnie.
(Wybrałem 4, ponieważ to jest to, co współczesny sprzęt najprawdopodobniej bezpośrednio obsługuje; termin „wektoryzacja” jest również używany do opisania transformacji oprogramowania wyższego poziomu, w której można po prostu całkowicie oderwać pętlę i po prostu opisać działanie na tablicach zamiast elementów które je obejmują)
Różnica między wektoryzacją a rozwijaniem pętli: Rozważ następującą bardzo prostą pętlę, która dodaje elementy dwóch tablic i przechowuje wyniki do trzeciej tablicy.
for (int i=0; i<16; ++i)
C[i] = A[i] + B[i];
Rozwinięcie tej pętli przekształciłoby ją w coś takiego:
for (int i=0; i<16; i+=4) {
C[i] = A[i] + B[i];
C[i+1] = A[i+1] + B[i+1];
C[i+2] = A[i+2] + B[i+2];
C[i+3] = A[i+3] + B[i+3];
}
Z drugiej strony wektoryzacja daje coś takiego:
for (int i=0; i<16; i+=4)
addFourThingsAtOnceAndStoreResult(&C[i], &A[i], &B[i]);
Gdzie „addFourThingsAtOnceAndStoreResult” jest symbolem zastępczym dla wszystkich elementów wewnętrznych używanych przez kompilator do określania instrukcji wektorowych. Zauważ, że niektóre kompilatory są w stanie automatycznie wektoryzować bardzo proste pętle, takie jak ta, które często można włączyć za pomocą opcji kompilacji. Bardziej złożone algorytmy nadal wymagają pomocy programisty w celu wygenerowania dobrego kodu wektorowego.
Wektoryzacja to termin konwertowania programu skalarnego na program wektorowy. Wektoryzowane programy mogą uruchamiać wiele operacji z jednej instrukcji, podczas gdy skalar może działać tylko na parach operandów jednocześnie.
Z wikipedii :
Podejście skalarne:
for (i = 0; i < 1024; i++)
{
C[i] = A[i]*B[i];
}
Podejście wektoryzowane:
for (i = 0; i < 1024; i+=4)
{
C[i:i+3] = A[i:i+3]*B[i:i+3];
}
Odnosi się do możliwości wykonywania pojedynczej operacji matematycznej na liście - lub „wektorze” - liczb w jednym kroku. Widzisz to często w Fortranie, ponieważ wiąże się to z obliczeniami naukowymi, które są związane z superkomputerami, w których po raz pierwszy pojawiła się arytmetyka wektorowy. Obecnie prawie wszystkie procesory do komputerów stacjonarnych oferują pewną formę wektorowej arytmetyki dzięki technologiom takim jak SSE Intela. Procesory graficzne oferują również formę wektorowej arytmetyki.
Wektoryzacja jest szeroko stosowana w obliczeniach naukowych, w których ogromne ilości danych muszą być przetwarzane wydajnie.
W prawdziwej aplikacji do programowania wiem, że jest używana w NUMPY (nie jestem pewien innych).
Numpy (pakiet do obliczeń naukowych w Pythonie), używa wektoryzacji do szybkiej manipulacji tablicą n-wymiarową, co ogólnie jest wolniejsze, jeśli jest zrobione z wbudowanymi opcjami Pythona do obsługi tablic.
chociaż dostępnych jest mnóstwo wyjaśnień, TUTAJ WEKTORYZACJA JEST OKREŚLONA JAK NA STRONIE NUMERYCZNEJ DOKUMENTACJI
Wektoryzacja opisuje brak wyraźnego zapętlenia, indeksowania itp. W kodzie - te rzeczy mają oczywiście miejsce „za kulisami” w zoptymalizowanym, wstępnie skompilowanym kodzie C. Kod wektorowy ma wiele zalet, między innymi:
kod wektorowy jest bardziej zwięzły i łatwiejszy do odczytania
mniej wierszy kodu zazwyczaj oznacza mniej błędów
kod bardziej przypomina standardową notację matematyczną (co zwykle ułatwia poprawne kodowanie konstrukcji matematycznych)
wektoryzacja powoduje powstanie kodu „Python”. Bez wektoryzacji nasz kod byłby zaśmiecony nieefektywnymi i trudnymi do odczytania pętlami.
Wektoryzacja, w prostych słowach, oznacza optymalizację algorytmu, aby mógł on wykorzystywać instrukcje SIMD w procesorach.
AVX, AVX2 i AVX512 to zestawy instrukcji (intel), które wykonują tę samą operację na wielu danych w jednej instrukcji. na przykład AVX512 oznacza, że możesz operować 16 wartościami całkowitymi (4 bajty) jednocześnie. Oznacza to, że jeśli masz wektor 16 liczb całkowitych i chcesz podwoić tę wartość w każdej liczbie całkowitej, a następnie dodać do niej 10. Możesz albo załadować wartości do rejestru ogólnego [a, b, c] 16 razy i wykonać tę samą operację lub możesz wykonać tę samą operację, ładując wszystkie 16 wartości do rejestrów SIMD [xmm, ymm] i wykonać operację raz. Pozwala to przyspieszyć obliczenia danych wektorowych.
W wektoryzacji wykorzystujemy to na naszą korzyść, przebudowując nasze dane, abyśmy mogli wykonywać na nim operacje SIMD i przyspieszyć program.
Jedynym problemem związanym z wektoryzacją są warunki obsługi. Ponieważ warunki rozgałęziają przepływ wykonania. Można to rozwiązać przez maskowanie. Modelując warunek w operację arytmetyczną. na przykład. jeśli chcemy dodać 10 do wartości, jeśli jest ona większa niż 100. możemy również.
if(x[i] > 100) x[i] += 10; // this will branch execution flow.
lub możemy zamodelować warunek na operację arytmetyczną, tworząc wektor warunku c,
c[i] = x[i] > 100; // storing the condition on masking vector
x[i] = x[i] + (c[i] & 10) // using mask
jest to jednak bardzo trywialny przykład ... dlatego c jest naszym wektorem maskującym, którego używamy do wykonywania operacji binarnych na podstawie jego wartości. Pozwala to uniknąć rozgałęzienia przepływu wykonania i umożliwia wektoryzację.
Wektoryzacja jest równie ważna jak równoległość. Dlatego powinniśmy z niego korzystać w jak największym stopniu. Wszystkie współczesne procesory mają instrukcje SIMD dla dużych obciążeń obliczeniowych. Możemy zoptymalizować nasz kod, aby używał instrukcji SIMD za pomocą wektoryzacji, jest to podobne do paralelizacji naszego kodu, aby działał na wielu rdzeniach dostępnych w nowoczesnych procesorach.
Chciałbym odejść od wzmianki o OpenMP, która pozwala wektoryzować kod za pomocą pragmy. Uważam to za dobry punkt wyjścia. To samo można powiedzieć o OpenACC.
Myślę, że przez ludzi Intela łatwo to zrozumieć.
Wektoryzacja to proces przekształcania algorytmu z działania na pojedynczej wartości naraz na działanie na zestawie wartości naraz . Nowoczesne procesory zapewniają bezpośrednie wsparcie dla operacji wektorowych, w których jedna instrukcja jest stosowana do wielu danych (SIMD).
Na przykład procesor z 512-bitowym rejestrem może pomieścić 16 32-bitowych podwójnych pojedynczych precyzji i wykonać pojedyncze obliczenia.
16 razy szybsze niż wykonywanie pojedynczych instrukcji na raz. Połączenie tego z wątkami i procesorami wielordzeniowymi prowadzi do wzrostu wydajności rzędu rzędów wielkości.
W Javie istnieje możliwość włączenia tego do Jdk 15 z 2020 r. Lub późno o JDK 16 o 2021 r.
Zobacz dwie odpowiedzi powyżej. Chciałem tylko dodać, że powodem wektoryzacji jest to, że superkomputery i wieloprocesory mogą z łatwością wykonywać te operacje w paśmie, co daje duży wzrost wydajności. Na komputerach jednoprocesorowych nie będzie wzrostu wydajności.