
SIMD deve ser conhecido por todo desenvolvedor para ganhar performance
O que é SIMD e por que todo desenvolvedor deveria conhecer
SIMD (Single Instruction, Multiple Data) permite que a CPU processe múltiplos valores em paralelo com uma única instrução - por exemplo, comparar 4, 8 ou 16 bytes de uma vez em vez de um por um. Mitchell Hashimoto, criador do Ghostty (emulador de terminal), argumenta que a técnica tem reputação injusta de complexidade e que o caso comum segue sempre o mesmo padrão de cinco passos.
O padrão de cinco passos
- Broadcast de constantes: copiar valores de comparação para todas as lanes do vetor (ex.:
@splat(0xF)). - Loop por chunks de vetor: iterar sobre a entrada carregando um vetor completo por vez (ex.: 8 valores com AVX2).
- Operação SIMD: aplicar a comparação ou aritmética em todas as lanes em paralelo - um único
>compara 8 valores de uma vez. - Redução do resultado: transformar o vetor de booleanos em algo utilizável (ex.: bitmask +
@ctzpara encontrar a primeira lane que falhou). - Cauda escalar: o loop original processa os elementos restantes que não preenchem um vetor completo e serve como fallback para CPUs sem suporte.
Exemplo real no Ghostty
O caso mostrado é um loop que escaneia codepoints decodificados até encontrar um caractere de controle C0 (valor ≤ 0xF). A versão escalar é uma linha. A versão SIMD adiciona 12 linhas e entrega até 4x de ganho com ARM NEON (Apple Silicon), 8x com AVX2 (x86 moderno) e 16x com AVX-512 (Intel e AMD Zen 4+). Em throughput real de ponta a ponta num desktop Intel com AVX2, o ganho foi de 5x.
Por que o compilador não faz isso sozinho?
Compiladores conseguem auto-vetorizar loops aritméticos simples, mas são limitados e frequentemente perdem oportunidades - pesquisa recente ainda documenta esse problema. Além disso, quando o loop é crítico o suficiente para justificar 5x de ganho, Hashimoto prefere que a vetorização seja explícita e previsível, sem risco de uma mudança de código ou atualização de compilador reverter silenciosamente para escalar.
Conclusão
O autor defende que todo desenvolvedor deveria ao menos reconhecer a oportunidade: ao ver um loop quente que escaneia, compara, conta ou transforma grandes volumes de dados contíguos, imagine processá-lo em chunks de vetor. Com bom suporte de linguagem (o post usa Zig, mas o conceito é geral), não é preciso conhecer assembly nem detalhes específicos de CPU para obter ganhos significativos.