Avisos e erros de paralelização automática
Autoparalelizador e Autovetorizador foram projetados para fornecer ganhos de desempenho automática de loops em seu código.
Autoparalelizador
O /Qpar permite a opção de compilador a paralelização automática de loops em seu código. Quando você especifica esse sinalizador sem modificar o código existente, o compilador avalia o código para localizar loops que podem se beneficiar de paralelização. Como talvez descubra loops que não fazem muito trabalho e, portanto, não se beneficiar da paralelização, e cada paralelização desnecessária pode engender a geração de um pool de threads, sincronização extra ou outro processamento tentarão reduzir o desempenho em vez de melhorá-lo, o compilador é conservadora ao selecionar os loops que ele processa. Por exemplo, considere o exemplo a seguir 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 automaticamente paralelização desse loop. No entanto, ainda convém ele paralelizado porque você sabe que u sempre será grande. Para habilitar a paralelização automática, especifique #pragma loop(hint_parallel(n)), onde n é o número de threads em paralelo em. No exemplo a seguir, o compilador tenta colocar o loop em paralelo em threads de 8.
void loop_test(int u) {
#pragma loop(hint_parallel(8))
for (int i=0; i<u; ++i)
A[i] = B[i] * C[i];
}
Assim como acontece com todos os diretivas pragma, a sintaxe alternativa pragma __pragma(loop(hint_parallel(n))) também tem suporte.
Há alguns loops que o compilador não pode colocar em paralelo, mesmo que você deseja. Veja 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 ser alterado toda vez que ele é chamado. Porque o limite superior não pode ser conhecido, o compilador pode emitir uma mensagem de diagnóstico que explica por que ele não é possível colocar esse loop. O exemplo a seguir demonstra um loop que pode ser colocado em paralelo, um loop que não pode ser colocado em paralelo, o compilador sintaxe 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;
}
}
Compilar usando este comando:
cl d:\myproject\mylooptest.cpp /O2 /Qpar /Qpar-report:1
produz esta saída:
--- Analyzing function: void __cdecl test(void)
d:\myproject\mytest.cpp(4) : loop parallelized
Compilar usando este comando:
cl d:\myproject\mylooptest.cpp /O2 /Qpar /Qpar-report:2
produz 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 os dois diferentes /Qpar-report (nível de relatórios do paralelizador automático) opções. /Qpar-report:1gera mensagens paralelizador apenas loops com êxito são colocados em paralelo. /Qpar-report:2gera mensagens paralelizador para ambos os parallelizations loop bem-sucedidas e malsucedidas.
Para obter mais informações sobre códigos de motivo e mensagens, consulte Mensagens do vetorizador e do paralelizador.
Vetorizador automático
O Autovetorizador analisa loops em seu código e usa os registros de vetor e instruções no computador de destino para executá-los, se for possível. Isso pode melhorar o desempenho do seu código. O compilador tem como alvo as instruções SSE2, AVX e AVX2 em processadores Intel ou AMD ou as instruções de NEON em processadores ARM, conforme o /arch alternar.
Autovetorizador pode gerar instruções diferentes do especificado pelo /arch alternar. Estas instruções são protegidas por uma verificação de tempo de execução para certificar-se de que código ainda seja executado corretamente. Por exemplo, quando você compila /arch:SSE2, instruções SSE 4.2 podem ser emitidas. Uma verificação em runtime verifica se o SSE 4.2 está disponível no processador de destino e vai para uma versão não SSE 4.2 do loop se o processador não oferece suporte a essas instruções.
Por padrão, o Vetorizador automático está habilitado. Se você deseja comparar o desempenho do seu código em vetorização, você poderá usar #pragma loop(no_vector) para desabilitar a vetorização do loop qualquer determinado.
#pragma loop(no_vector)
for (int i = 0; i < 1000; ++i)
A[i] = B[i] + C[i];
Assim como acontece com todos os diretivas pragma, a sintaxe alternativa pragma __pragma(loop(no_vector)) também tem suporte.
Como com o Autoparalelizador, você pode especificar o /Qvec-report (nível de relatórios do vetorizador automático) a opção de linha de comando para relatar qualquer um com êxito vetorizado apenas loops —/Qvec-report:1— ou ambos com êxito e sem êxito vetorizado loops —/Qvec-report:2).
Para obter mais informações sobre códigos de motivo e mensagens, consulte Mensagens do vetorizador e do paralelizador.
Para obter um exemplo mostrando como o vetorizador funciona na prática, consulte Project Austin parte 2 de 6: página Curling
Consulte também
Referência
/Qpar (paralelizador automático)
/Qpar-report (nível de relatórios do paralelizador automático)
/Qvec-report (nível de relatórios do vetorizador automático)