Automatická paralelizace a automatická vektorizace

Automatické paralelizace a auto-vektorizace jsou navržené tak, aby poskytovaly automatické nárůsty výkonu pro smyčky ve vašem kódu.

Automatické paralelizace

Přepínač kompilátoru /Qpar umožňuje Automatické paralelismuing smyček ve vašem kódu. Při zadání tohoto příznaku beze změny stávajícího kódu kompilátor vyhodnotí kód pro hledání smyček, které by mohly těžit z paralelismu. Vzhledem k tomu, že by mohlo dojít k nalezení smyček, které nedělají spoustu práce, a proto nebude výhoda paralelního zpracování, protože každý zbytečný paralelismus může engender vytváření fondu vláken, další synchronizaci nebo jiné zpracování, které by pomohly zpomalit výkon namísto jeho vylepšení, je při výběru smyček, které parallelizes, kompilátor konzervativní. Zvažte například následující příklad, ve kterém není horní mez smyčky v době kompilace známa:

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

Vzhledem u k tomu, že by mohla být malá hodnota, kompilátor tuto smyčku automaticky paralelizovat. Přesto ale budete chtít, aby byl váš i stále rovnoběžný, protože víte, že u budou vždy velké. Chcete-li povolit automatické paralelismuing, zadejte #pragma smyčka (hint_parallel (n)), kde je počet vláken, která se mají paralelizovat napříč. V následujícím příkladu se kompilátor pokusí paralelizovat smyčku napříč 8 vlákny.

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

Stejně jako u všech direktiv pragma je také podporována alternativní syntaxe pragma.

Existují některé cykly, které kompilátor nemůže paralelizovat, i když chcete. Tady je příklad:

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

Funkce se upper_bound() může změnit pokaždé, když je volána. Vzhledem k tomu, že horní mez nelze znát, kompilátor může vygenerovat diagnostickou zprávu s vysvětlením, proč nemůže tuto smyčku paralelizovat. Následující příklad ukazuje smyčku, která může být paralelní, smyčka, která nemůže být paralelní, syntaxe kompilátoru použitá na příkazovém řádku a výstup kompilátoru pro jednotlivé parametry příkazového řádku:

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

Kompilace pomocí tohoto příkazu:

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

vypočítá tento výstup:

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

Kompilace pomocí tohoto příkazu:

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

vypočítá tento výstup:

--- 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'

Všimněte si rozdílu ve výstupu mezi dvěma různými možnostmi /Qpar-Report (úroveň vytváření sestav auto-paralelizace) . /Qpar-report:1 Vytvoří výstup zpráv paralelizace jenom pro cykly, které jsou úspěšně paralelismuované. /Qpar-report:2 Vypíše zprávy paralelizace pro úspěšné i neúspěšné parallelizations smyčky.

Další informace o kódech a zprávách důvodů naleznete v tématu vektorizace and paralelizace Messages.

Automatické vektorizace

Automatické vektorizace analyzuje smyčky v kódu a používá vektorové registry a pokyny v cílovém počítači k jejich spuštění, pokud je může. To může zlepšit výkon kódu. Kompilátor cílí na instrukce SSE2, AVX a AVX2 v procesorech Intel nebo AMD nebo na procesorech ARM v závislosti na přepínači /arch .

Automatické vektorizace můžou vygenerovat jiné pokyny, než je zadané v /arch přepínači. Tyto pokyny jsou chráněny pomocí kontroly za běhu, aby se zajistilo, že kód stále běží správně. Například když kompilujete /arch:SSE2 , mohou být vygenerovány pokyny SSE 4.2. Při kontrole za běhu se ověří, jestli je v cílovém procesoru k dispozici SSE 4.2, a přejde na verzi smyčky, která není SSE 4.2, pokud procesor tyto pokyny nepodporuje.

Ve výchozím nastavení je povolená možnost auto-vektorizace. Chcete-li porovnat výkon kódu v rámci vektorování, můžete použít #pragma smyčka (no_vector) , chcete-li zakázat rozvektorování kterékoli dané smyčky.

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

Stejně jako u všech direktiv pragma je také podporována alternativní syntaxe pragma.

Stejně jako u auto-paralelizace můžete zadat možnost příkazového řádku /Qvec-Report (auto-vektorizace Reporting Level) , která bude hlásit buď úspěšně vektorové smyčky, nebo úspěšné i neúspěšně vektorové smyčky – /Qvec-report:2 ).

Další informace o kódech a zprávách důvodů naleznete v tématu vektorizace and paralelizace Messages.

příklad ukazující, jak vektorizace funguje v praxi, najdete v tématu Project Austin část 2 z 6: vystránkování stránky.

Viz také

loop
Paralelní programování v nativním kódu
/Qpar (auto-paralelizace)
/Qpar-Report (úroveň vytváření sestav auto paralelizace)
/Qvec-Report (úroveň vytváření sestav auto vektorizace)
Zprávy vektorizace a paralelizace