Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O Auto-Parallelizer e o Auto-Vectorizer são projetados para fornecer ganhos automáticos de desempenho para loops em seu código.
Automatizador de Paralelização
O switch do compilador /Qpar permite a paralelização automática de loops em seu código. Quando você especifica esse sinalizador sem alterar o código existente, o compilador avalia o código para encontrar loops que podem se beneficiar da paralelização. Como ele pode encontrar loops que não fazem muito trabalho e, portanto, não se beneficiarão da paralelização, e porque cada paralelização desnecessária pode gerar a geração de um pool de threads, sincronização extra ou outro processamento que tenderia a diminuir o desempenho em vez de melhorá-lo, o compilador é conservador na seleção dos loops que paraleliza. Por exemplo, considere o seguinte exemplo em que o limite superior do loop não é conhecido em tempo de compilação:
void loop_test(int u) {
for (int i=0; i<u; ++i)
A[i] = B[i] * C[i];
}
Como u pode ser um valor pequeno, o compilador não paralelizará automaticamente esse loop. No entanto, pode ainda querer paralelizar, pois sabe que u será sempre grande. Para habilitar a paralelização automática, especifique #pragma loop(hint_parallel(n)), onde n é o número de threads a serem paralelizados. No exemplo a seguir, o compilador tentará paralelizar o loop em 8 threads.
void loop_test(int u) {
#pragma loop(hint_parallel(8))
for (int i=0; i<u; ++i)
A[i] = B[i] * C[i];
}
Tal como acontece com todas as diretivas pragma, a sintaxe __pragma(loop(hint_parallel(n))) pragma alternativa também é suportada.
Existem alguns loops que o compilador não pode paralelizar, mesmo que você queira. Aqui está um exemplo:
#pragma loop(hint_parallel(8))
for (int i=0; i<upper_bound(); ++i)
A[i] = B[i] * C[i];
A função upper_bound() pode mudar sempre que é chamada. Como o limite superior não pode ser conhecido, o compilador pode emitir uma mensagem de diagnóstico que explica por que ele não pode paralelizar esse loop. O exemplo a seguir demonstra um loop que pode ser paralelizado, um loop que não pode ser paralelizado, a sintaxe do compilador a ser usada no prompt de comando e a saída do compilador para cada opção de linha de comando:
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;
}
}
Compilando usando este comando:
cl d:\myproject\mylooptest.cpp /O2 /Qpar /Qpar-report:1
gera esta saída:
--- Analyzing function: void __cdecl test(void)
d:\myproject\mytest.cpp(4) : loop parallelized
Compilando usando este comando:
cl d:\myproject\mylooptest.cpp /O2 /Qpar /Qpar-report:2
gera esta saída:
--- 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'
Observe a diferença na saída entre as duas opções diferentes /Qpar-report (Auto-Parallelizer Reporting Level).
/Qpar-report:1 Emite mensagens do paralelizador somente para loops que são paralelizados com êxito.
/Qpar-report:2 Emite mensagens do paralelizador para paralelizações de loop bem-sucedidas e malsucedidas.
Para obter mais informações sobre códigos de causa e mensagens, consulte Mensagens de vetorização e paralelização.
Auto-vetorizador
O Auto-Vectorizer analisa loops em seu código e usa os registros vetoriais e instruções no computador de destino para executá-los, se possível. Isso pode melhorar o desempenho do seu código. O compilador tem como alvo as instruções SSE2, AVX e AVX2 nos processadores Intel ou AMD, ou as instruções NEON nos processadores ARM, de acordo com o switch /arch .
O Auto-Vectorizer pode gerar instruções diferentes das especificadas pelo /arch switch. Essas instruções são protegidas por uma verificação de tempo de execução para garantir que o código ainda seja executado corretamente. Por exemplo, quando você compila /arch:SSE2, instruções SSE4.2 podem ser emitidas. Uma verificação de tempo de execução verifica se SSE4.2 está disponível no processador de destino e salta para uma versão não-SSE4.2 do loop se o processador não suportar essas instruções.
Por padrão, o Auto-Vectorizer está ativado. Se você quiser comparar o desempenho do seu código sob vetorização, você pode usar #pragma loop(no_vetor) para desativar a vetorização de qualquer loop.
#pragma loop(no_vector)
for (int i = 0; i < 1000; ++i)
A[i] = B[i] + C[i];
Tal como acontece com todas as diretivas pragma, a sintaxe __pragma(loop(no_vector)) pragma alternativa também é suportada.
Assim como acontece com o Auto-Parallelizer, você pode especificar a opção de linha de comando /Qvec-report (Auto-Vectorizer Reporting Level) para relatar apenas loops vetorizados com êxito —/Qvec-report:1 ou loops vetorizados com ou sem êxito —/Qvec-report:2).
Para obter mais informações sobre códigos de causa e mensagens, consulte Mensagens de vetorização e paralelização.
Para obter um exemplo mostrando como o vetorizador funciona na prática, consulte Project Austin Parte 2 de 6: Page Curling
Ver também
ciclo
Programação paralela em código nativo
/Qpar (Auto-Paralelizador)
/qpar-report (nível de relatório do paralelizador automático)
/qvec-report (nível de relatório do vetorizador automático)
Mensagens vetorizadoras e paralelizadoras