Co to jest „wektoryzacja”?


190

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”?


1
@geoffspear Wygląda na to, że link został przeniesiony na en.wikipedia.org/wiki/Array_programming
Lubię kod

Odpowiedzi:


225

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.


11
Jaka jest różnica między tym a rozwijaniem / rozwijaniem pętli?
Jeremy Powell,

1
Czy nie jest prawdą, że kompilator miałby łatwiejsze zadanie auto-wektoryzacji rozwijanej pętli?
Nikos Athanasiou,

@NikosAthanasiou: Jest to prawdopodobne, ale ogólnie mówiąc, kompilator powinien być zdolny do autowektoryzacji obu pętli, ponieważ oba są dość proste.
Stephen Canon

1
@StephenCanon jak sprawdzić, czy niektóre linie zostały wektoryzowane? Gdyby ktoś użył objdump, czego by szukał w danych wyjściowych objdump?
user1823664

3
@Shuklaswag: wektoryzacja jest czymś, co kompilatory mogą dla Ciebie zrobić, ale jest także czymś, co programiści robią sami. System operacyjny nie jest zaangażowany.
Stephen Canon

32

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];
}

czy nie jest to w istocie to samo, co podejście skalarne? Twoja składnia i przesuwanie w pętli jest inna, ale poniżej wciąż ją mnożycie 4 razy. Ale jakoś będzie szybciej, prawdopodobnie procesor ma instrukcje, które wykonują sztuczkę zwaną wektoryzacją.
mskw

Wygląda na to, że odpowiem tutaj na własne pytanie. Składnia w podejściu do wektoryzacji, gdy kompilator to zobaczy, przełoży ją na zoptymalizowane instrukcje procesora, które zwielokrotniają wektory. Jak SIMD.
mskw

10

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.


7

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:

  1. kod wektorowy jest bardziej zwięzły i łatwiejszy do odczytania

  2. mniej wierszy kodu zazwyczaj oznacza mniej błędów

  3. kod bardziej przypomina standardową notację matematyczną (co zwykle ułatwia poprawne kodowanie konstrukcji matematycznych)

  4. wektoryzacja powoduje powstanie kodu „Python”. Bez wektoryzacji nasz kod byłby zaśmiecony nieefektywnymi i trudnymi do odczytania pętlami.


4

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.


0

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.

Link https://software.intel.com/en-us/articles/vectorization-a-key-tool-to-improve-performance-on-modern-cpus

W Javie istnieje możliwość włączenia tego do Jdk 15 z 2020 r. Lub późno o JDK 16 o 2021 r.

https://bugs.openjdk.java.net/browse/JDK-8201271


-4

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.


12
„Na komputerach z jednym procesorem nie nastąpi wzrost wydajności”: nieprawda. Większość współczesnych procesorów ma (ograniczoną) obsługę sprzętową wektoryzacji (SSE, Altivec itp., Zgodnie z nazwą stephentyrone), co może znacznie przyspieszyć użycie.
sleske

dzięki, zapomniałem, że równoległości można dokonać również na tym poziomie.
Larry Watanabe
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.