Partilhar via


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

loop

/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)

Outros recursos

Programação de Paralelo no Código Nativo

Mensagens do vetorizador e do paralelizador