O que é "vetorização"?

190

Várias vezes agora, encontrei esse termo no matlab, fortran ... em outro ... mas nunca encontrei uma explicação sobre o que isso significa e o que faz? Então, eu estou perguntando aqui, o que é vetorização e o que significa, por exemplo, que "um loop é vetorizado"?

Thomas Geritzma
fonte
1
@geoffspear O link parece ter sido movido para en.wikipedia.org/wiki/Array_programming
Eu gosto de codificar

Respostas:

225

Muitas CPUs possuem conjuntos de instruções "vetor" ou "SIMD" que aplicam a mesma operação simultaneamente a dois, quatro ou mais dados. Os chips x86 modernos têm as instruções SSE, muitos chips PPC têm as instruções "Altivec" e até alguns chips ARM têm um conjunto de instruções vetoriais, chamado NEON.

"Vetorização" (simplificado) é o processo de reescrever um loop para que, em vez de processar um único elemento de uma matriz N vezes, processe (digamos) 4 elementos da matriz simultaneamente N / 4 vezes.

(Escolhi 4 porque é mais provável que o hardware moderno ofereça suporte direto; o termo "vetorização" também é usado para descrever uma transformação de software de nível superior, na qual você pode abstrair completamente o loop e descrever a operação em matrizes em vez dos elementos que os compõem)


A diferença entre vetorização e desenrolamento de loop: Considere o seguinte loop muito simples que adiciona os elementos de duas matrizes e armazena os resultados em uma terceira matriz.

for (int i=0; i<16; ++i)
    C[i] = A[i] + B[i];

Desenrolar esse loop o transformaria em algo assim:

for (int i=0; i<16; i+=4) {
    C[i]   = A[i]   + B[i];
    C[i+1] = A[i+1] + B[i+1];
    C[i+2] = A[i+2] + B[i+2];
    C[i+3] = A[i+3] + B[i+3];
}

A vetorização, por outro lado, produz algo como isto:

for (int i=0; i<16; i+=4)
    addFourThingsAtOnceAndStoreResult(&C[i], &A[i], &B[i]);

Onde "addFourThingsAtOnceAndStoreResult" é um espaço reservado para quaisquer intrínsecos que seu compilador usa para especificar instruções de vetor. Observe que alguns compiladores são capazes de vetorizar automaticamente loops muito simples como esse, que geralmente podem ser ativados por meio de uma opção de compilação. Algoritmos mais complexos ainda precisam da ajuda do programador para gerar um bom código vetorial.

Stephen Canon
fonte
11
Qual é a diferença entre isso e desenrolar / desenrolar o loop?
Jeremy Powell
1
Não é verdade que um compilador teria um trabalho mais fácil de vetorizar automaticamente o loop desenrolado?
Nikos Athanasiou
@NikosAthanasiou: É plausível, mas, de um modo geral, um compilador deve poder autovectorizar qualquer um dos loop, pois ambos são bastante simples.
Stephen Canon
1
@StephenCanon como verificar se algumas linhas foram ou não vetorizadas? Se alguém usasse o objdump, o que procuraria na saída do objdump?
precisa saber é o seguinte
3
@Shuklaswag: vetorização é algo que os compiladores podem fazer por você, mas também é algo que os programadores explicitamente fazem. O sistema operacional não está envolvido.
Stephen Canon
32

Vetorização é o termo para converter um programa escalar em um programa vetorial. Programas vetorizados podem executar várias operações a partir de uma única instrução, enquanto escalar pode operar apenas em pares de operandos de uma só vez.

Da wikipedia :

Abordagem escalar:

for (i = 0; i < 1024; i++)
{
   C[i] = A[i]*B[i];
}

Abordagem vetorizada:

for (i = 0; i < 1024; i+=4)
{
   C[i:i+3] = A[i:i+3]*B[i:i+3];
}
Anders
fonte
isso não é essencialmente o mesmo que a abordagem escalar? Sua sintaxe e o avanço do loop são diferentes, mas por baixo você ainda está multiplicando-o 4 vezes. Mas, de alguma forma, será mais rápido, provavelmente a CPU possui instruções que fazem algum truque chamado Vetorização.
mskw
Parece que vou responder minha própria pergunta aqui. A sintaxe na abordagem de vetorização, quando o complier vê isso, o traduz em instruções de CPU otimizadas que multiplicam vetores. Como SIMD.
mskw
10

Refere-se à capacidade de executar uma operação matemática única em uma lista - ou "vetor" - de números em uma única etapa. Você o vê frequentemente com o Fortran porque está associado à computação científica, associada à supercomputação, onde a aritmética vetorizada apareceu pela primeira vez. Atualmente, quase todas as CPUs de desktop oferecem alguma forma de aritmética vetorizada, através de tecnologias como o SSE da Intel. As GPUs também oferecem uma forma de aritmética vetorizada.

Warren Young
fonte
7

A vetorização é muito usada na computação científica, em que grandes quantidades de dados precisam ser processadas com eficiência.

Na aplicação de programação real, eu sei que é usado em NUMPY (não tenho certeza de outra coisa).

O Numpy (pacote para computação científica em python), usa vetorização para manipulação rápida de matriz n-dimensional, que geralmente é mais lenta se feita com opções de python embutidas para manipular matrizes.

Embora existam toneladas de explicações, aqui está a definição de que a vetor é definida na página de documentação NUMPY

A vetorização descreve a ausência de loop, indexação, etc. explícitos no código - essas coisas estão ocorrendo, é claro, apenas "nos bastidores" em código C otimizado e pré-compilado. O código vetorizado tem muitas vantagens, entre as quais:

  1. código vetorizado é mais conciso e fácil de ler

  2. menos linhas de código geralmente significa menos erros

  3. o código se assemelha mais à notação matemática padrão (tornando mais fácil, normalmente, codificar corretamente construções matemáticas)

  4. a vetorização resulta em um código mais “Pythonic”. Sem vetorização, nosso código seria repleto de ineficientes e difíceis de ler para loops.

programador ruim
fonte
4

A vetorização, em palavras simples, significa otimizar o algoritmo para que ele possa utilizar instruções SIMD nos processadores.

AVX, AVX2 e AVX512 são os conjuntos de instruções (intel) que executam a mesma operação em vários dados em uma instrução. por exemplo. AVX512 significa que você pode operar com 16 valores inteiros (4 bytes) por vez. O que isso significa é que, se você tiver um vetor de 16 números inteiros e quiser duplicar esse valor em cada número inteiro, adicione 10 a ele. Você pode carregar valores no registro geral [a, b, c] 16 vezes e executar a mesma operação ou pode executar a mesma operação carregando todos os 16 valores nos registros SIMD [xmm, ymm] e executar a operação uma vez. Isso permite acelerar o cálculo dos dados vetoriais.

Na vetorização, usamos isso para nossa vantagem, remodelando nossos dados para que possamos executar operações SIMD nele e acelerar o programa.

O único problema com a vetorização é lidar com as condições. Porque as condições ramificam o fluxo de execução. Isso pode ser tratado com mascaramento. Modelando a condição em uma operação aritmética. por exemplo. se quisermos adicionar 10 ao valor, se for maior que 100. também podemos.

if(x[i] > 100) x[i] += 10; // this will branch execution flow.

ou podemos modelar a condição em operação aritmética, criando um vetor de condição c,

c[i] = x[i] > 100; // storing the condition on masking vector
x[i] = x[i] + (c[i] & 10) // using mask

esse é um exemplo muito trivial ... portanto, c é o nosso vetor de máscara que usamos para executar a operação binária com base em seu valor. Isso evita a ramificação do fluxo de execução e permite a vetorização.

A vetorização é tão importante quanto a paralelização. Portanto, devemos usá-lo o máximo possível. Todos os processadores modernos têm instruções SIMD para cargas de trabalho pesadas de computação. Podemos otimizar nosso código para usar essas instruções SIMD usando vetorização. Isso é semelhante a paralelizar nosso código para executar em vários núcleos disponíveis nos processadores modernos.

Gostaria de sair com a menção do OpenMP, que permite vetorizar o código usando pragmas. Eu considero isso um bom ponto de partida. O mesmo pode ser dito para o OpenACC.

Fila de mercado
fonte
0

Pelas pessoas da Intel, acho que é fácil de entender.

Vetorização é o processo de converter um algoritmo de operar em um único valor por vez para operar em um conjunto de valores ao mesmo tempo . As CPUs modernas fornecem suporte direto para operações vetoriais em que uma única instrução é aplicada a vários dados (SIMD).

Por exemplo, uma CPU com um registro de 512 bits pode conter 16 duplas de precisão única de 32 bits e fazer um único cálculo.

16 vezes mais rápido do que executar uma única instrução de cada vez. Combine isso com os processadores de threading e multi-core, levando a ganhos de desempenho de magnitude.

Link https://software.intel.com/pt-br/articles/vectorization-a-key-tool-to-improve-performance-on-modern-cpus

Em Java, há uma opção para isso ser incluído no Jdk 15 de 2020 ou atrasado no JDK 16 em 2021.

https://bugs.openjdk.java.net/browse/JDK-8201271

chiperortiz
fonte
-4

Veja as duas respostas acima. Eu só queria acrescentar que o motivo para querer fazer a vetorização é que essas operações podem ser facilmente executadas em paralelo por supercomputadores e multiprocessadores, gerando um grande ganho de desempenho. Em computadores com processador único, não haverá ganho de desempenho.

Larry Watanabe
fonte
12
"Em computadores com processador único, não haverá ganho de desempenho": não é verdade. A maioria dos processadores modernos possui suporte (limitado) a hardware para vetorização (SSE, Altivec etc., como nomeado por stephentyrone), o que pode acelerar significativamente quando usado.
sleske 14/09/09
obrigado, esqueci que a paralelização também pode ser feita nesse nível.
Larry Watanabe