Algoritmos SIMD projetados do zero
(mcyoung.xyz)Projeto de algoritmos SIMD
- Explicação sobre otimização com SIMD: SIMD significa instrução única, múltiplos dados, e é necessário pensar como um projetista de circuitos.
- SIMD é frequentemente mencionado em desempenho e HPC (computação de alto desempenho), mas não é um tema familiar para iniciantes.
- Na maioria das linguagens de programação, as APIs de programação SIMD são difíceis de usar.
- Algoritmos SIMD são difíceis de entender com uma mentalidade de programação procedural, e a programação funcional ajuda.
- O texto trata do vb64, que implementa um codec base64 usando a biblioteca
std::simddo Rust.
Limites físicos
- Computadores existem no mundo real e são restringidos pelas leis da física.
- Na era inicial da computação, era possível melhorar o desempenho comprando um computador novo.
- O efeito do escalonamento de Dennard entrou em colapso, então transistores menores passaram a significar maior consumo de energia.
- Aumentar o número de núcleos tornou-se a nova tendência. É possível melhorar o desempenho da CPU com multithreading, mas isso gera sobrecarga de sincronização.
A lentidão do código procedural
- Núcleos de computadores modernos não executam código linha por linha.
- Por meio do paralelismo em nível de instrução, várias operações podem ser realizadas ao mesmo tempo quando não há dependência de dados.
- O paralelismo aumenta quando o compilador consegue resolver riscos de dados.
- Desvios e operações de memória causam stalls, o que torna o código mais lento.
SIMD e lanes
- SIMD e vetores são frequentemente usados como sinônimos.
- Instruções SIMD usam como unidade básica vetores, que são arrays de tamanho fixo de números.
- Cada elemento do vetor é chamado de lane, e vetores SIMD geralmente têm tamanho pequeno.
Operações sobre vetores reais
- Vetores SIMD oferecem operações mais complexas do que registradores comuns.
- Registradores vetoriais suportam várias operações, como operações de bits, aritmética por lane, comparação por lane e shuffle.
- O shuffle é importante na programação SIMD para mover os dados para as posições adequadas.
Intrínsecos e seleção de instruções
- Ao escrever código SIMD, as operações disponíveis variam conforme a arquitetura.
- O compilador resolve o problema de seleção de instruções, decidindo quais instruções usar para as operações solicitadas pelo programador.
- Escrever código SIMD portátil é complexo, mas, com detecção de recursos em tempo de execução, é possível gerar o código ideal para diferentes processadores.
Parsing com SIMD
- É possível fazer parsing de texto com SIMD, e isso pode ser muito rápido.
- A implementação da decodificação de base64 com SIMD pode ser usada como exemplo.
- Remover todos os desvios é a chave no processo de criar uma versão SIMD.
Opinião do GN⁺
O ponto mais importante deste texto é que a programação SIMD, diferentemente da programação procedural tradicional, pode melhorar o desempenho ao processar dados em paralelo. SIMD é muito importante na área de computação de alto desempenho e, especialmente em linguagens modernas como Rust, entender como usar SIMD de forma eficaz pode ser um tema muito interessante para engenheiros de software. Isso porque, com SIMD, é possível aprender a otimizar algoritmos complexos e a superar os limites do hardware real.
1 comentários
Comentários do Hacker News
popcountpara uma única instrução, mas que isso é possível em outros casos._mm256_cvtps_epu32não é uma instrução de AVX2, e sim de AVX-512; em AVX1, os inteiros existem em forma com sinal e a instrução correspondente é_mm256_cvtps_epi32.popcntnão vetorizada gera um "código francamente ridículo", ao compilar em modo release para a CPU nativa, a função aparentemente é vetorizada de forma bastante razoável.