Udostępnij za pośrednictwem


Automatyczna paralelizacja i wektoryzacja

Automatyczne Parallelizer i automatycznie Vectorizer celem jest zwiększenie wydajności automatyczne dla pętli w kodzie.

Automatyczne Parallelizer

/Qpar umożliwia przełącznik automatyczne parallelization pętli w kodzie.Po określeniu tej flagi bez modyfikowania istniejących kodu, kompilator ocenia kodu, aby znaleźć pętle, które mogą korzystać z parallelization.Ponieważ może okazać się pętle, które nie ilość pracy i dlatego nie korzystać z parallelization, a co niepotrzebne parallelization może stanowić zagrożenie duplikowanie puli wątków, synchronizacji dodatkowe lub inne przetwarzania, które mogą one spowolnić działanie, a nie jej udoskonalania, kompilator jest konserwatywnego przy wyborze pętle, które go parallelizes.Na przykład należy wziąć pod uwagę w poniższym przykładzie, w którym górnej granicy pętli nie jest znany w czasie kompilacji:

void loop_test(int u) {
   for (int i=0; i<u; ++i)
      A[i] = B[i] * C[i];
}

Ponieważ u może być małej wartości, kompilator nie będzie automatycznie parallelize pętlę.Jednak nadal można go parallelized, ponieważ wiadomo, że u będzie zawsze duże.Aby włączyć automatyczne parallelization, należy określić #pragma loop(hint_parallel(n)), gdzie n to liczba wątków parallelize przez.W poniższym przykładzie kompilator podejmie próbę parallelize pętli między 8 wątków.

void loop_test(int u) {
#pragma loop(hint_parallel(8))
   for (int i=0; i<u; ++i)
      A[i] = B[i] * C[i];
}

Jak w przypadku wszystkich dyrektywy dyrektywę pragma, składni alternatywne dyrektywę pragma __pragma(loop(hint_parallel(n))) jest również obsługiwane.

Istnieją pewne pętle, które kompilator nie parallelize, nawet jeśli ma być.Oto przykład:

#pragma loop(hint_parallel(8))
for (int i=0; i<upper_bound(); ++i)
    A[i] = B[i] * C[i];

Funkcja upper_bound() może zmienić się za każdym razem, gdy jest ona wywoływana.Ponieważ nie może być znane górnej granicy kompilator może emitować diagnostyczne komunikat wyjaśnia, dlaczego nie mogę parallelize pętlę.W poniższym przykładzie pokazano pętli, który może być parallelized, pętla, która nie może być parallelized, składnia kompilator do użycia w wierszu polecenia, a dane wyjściowe kompilatora dla poszczególnych opcji wiersza polecenia:

int A[1000];
void test() {
#pragma loop(hint_parallel(0))
    for (int i=0; i<1000; ++i) {
        A[i] = A[i] + 1;
    }

    for (int i=1000; i<2000; ++i) {
        A[i] = A[i] + 1;
    }
}

Kompilowanie za pomocą tego polecenia:

cl d:\myproject\mylooptest.cpp /O2 /Qpar /Qpar-report:1

daje to wyjściowego:

--- Analyzing function: void __cdecl test(void)
d:\myproject\mytest.cpp(4) : loop parallelized

Kompilowanie za pomocą tego polecenia:

cl d:\myproject\mylooptest.cpp /O2 /Qpar /Qpar-report:2

daje to wyjściowego:

--- Analyzing function: void __cdecl test(void)
d:\myproject\mytest.cpp(4) : loop parallelized
d:\myproject\mytest.cpp(4) : loop not parallelized due to reason '1008'

Zwróć uwagę na wyjściu różnicę dwóch różnych /Qpar-raport (Poziom raportowania automatycznej paralelizacji) opcje./Qpar-report:1generuje komunikaty parallelizer tylko dla pętli, które są pomyślnie parallelized./Qpar-report:2generuje komunikaty parallelizer dla obu parallelizations pomyślne i niepomyślne pętli.

Aby uzyskać więcej informacji dotyczących kodów przyczyny i komunikaty, zobacz Komunikaty wektoryzatora i paralelizatora.

Automatyczne Vectorizer

Automatyczne — Vectorizer analizuje pętle w kodzie i używa rejestruje wektorową i instrukcje na komputerze docelowym do wykonania, jeśli można ją.Może to poprawić wydajność kodu.Kompilator przeznaczona dla instrukcji SSE2, AVX i AVX2 procesorów Intel lub AMD lub instrukcje NEONU na procesorach ARM, zgodnie z /Łuk wygięty przełączyć.

Automatyczne-Vectorizer może wygenerować różne instrukcje niż określony przez /arch przełączyć.Te instrukcje są chroniony przez sprawdzanie czasu wykonywania, aby upewnić się, że kod nadal działa poprawnie.Na przykład, jeśli kompilacja /arch:SSE2, mogą być emitowane SSE4.2 instrukcje.Zaznacz środowisko uruchomieniowe sprawdza, czy SSE4.2 jest dostępny na procesorze docelowy i przechodzi do wersji bez SSE4.2 pętli, jeśli procesor nie obsługuje tych instrukcji.

Domyślnie włączone jest automatycznie-Vectorizer.Jeśli chcesz porównać wydajność kodu w obszarze vectorization, można użyć #pragma loop(no_vector) wyłączyć vectorization dowolnym danego pętli.

#pragma loop(no_vector)
for (int i = 0; i < 1000; ++i)
   A[i] = B[i] + C[i];

Jak w przypadku wszystkich dyrektywy dyrektywę pragma, składni alternatywne dyrektywę pragma __pragma(loop(no_vector)) jest również obsługiwane.

Zgodnie z Parallelizer automatycznie, można określić /Qvec-raport (Poziom raportowania automatycznej wektoryzacji) opcji wiersza polecenia, aby zgłosić albo pomyślnie vectorized tylko pętli —/Qvec-report:1— lub obu pomyślnie i niepomyślnie vectorized pętli —/Qvec-report:2).

Aby uzyskać więcej informacji dotyczących kodów przyczyny i komunikaty, zobacz Komunikaty wektoryzatora i paralelizatora.

Na przykład pokazujący, jak działa vectorizer w praktyce, zobacz projektu Austin część 2 z 6: strony Curling

Zobacz też

Informacje

pętla

/Qpar (Automatyczny paralelizator)

/Qpar-raport (Poziom raportowania automatycznej paralelizacji)

/Qvec-raport (Poziom raportowania automatycznej wektoryzacji)

Inne zasoby

Parallel Programming in Native Code

Komunikaty wektoryzatora i paralelizatora