2 pontos por GN⁺ 2025-02-23 | 1 comentários | Compartilhar no WhatsApp

Introdução

  • Bem-vindo às aulas de linguagem assembly do FFmpeg. Este curso fornece a base de como a linguagem assembly é escrita no FFmpeg.

Conhecimentos necessários

  • É necessário conhecimento da linguagem C, especialmente sobre ponteiros.
  • É necessário conhecimento de matemática em nível de ensino médio (escalares e vetores, adição, multiplicação etc.).

O que é linguagem assembly?

  • Linguagem assembly é uma linguagem de programação em que se escreve código que corresponde diretamente às instruções processadas pela CPU.
  • A maior parte do código assembly do FFmpeg é SIMD (Single Instruction Multiple Data), também chamado de programação vetorial.
  • SIMD é adequado para processar grandes quantidades de dados armazenados sequencialmente na memória, como imagens, vídeo e áudio.

Por que escrever em linguagem assembly?

  • Para acelerar a velocidade do processamento multimídia. Ao escrever em código assembly, é possível obter ganhos de desempenho de mais de 10 vezes.
  • No FFmpeg, o código assembly é escrito diretamente sem usar intrinsics. Intrinsics geralmente são 10–15% mais lentos do que assembly escrito manualmente.

Tipos de linguagem assembly

  • Este curso se concentra em linguagem assembly x86 de 64 bits. Ela também é conhecida como amd64 e funciona também em CPUs Intel.
  • Há duas sintaxes de assembly x86, AT&T e Intel, e será usada a sintaxe Intel.

Material de apoio

  • A programação em assembly do FFmpeg é focada em processamento de imagens de alto desempenho e tem uma abordagem única.
  • Os diagramas do livro "The Art of 64-bit assembly" podem ser úteis.

Registradores

  • Registradores são áreas da CPU onde os dados são processados. A CPU não manipula diretamente a memória; ela carrega os dados nos registradores, os processa e depois os escreve de volta na memória.

Registradores de uso geral

  • Registradores de uso geral (GPR) podem conter dados ou endereços de memória. No código assembly do FFmpeg, os GPRs atuam principalmente como apoio.

Registradores vetoriais

  • Registradores vetoriais (SIMD) contêm vários elementos de dados. Existem vários tipos de registradores vetoriais.
  • A maior parte dos cálculos de compressão e descompressão de vídeo é baseada em inteiros.

Inclusão de x86inc.asm

  • x86inc.asm é uma camada leve de abstração usada no FFmpeg, x264 e dav1d para facilitar o trabalho de programadores assembly.

Código assembly escalar simples

  • O funcionamento do código assembly escalar é explicado por meio de exemplos.

Entendendo funções vetoriais básicas

  • O significado de cada linha é explicado por meio do primeiro exemplo de função SIMD.
  • Operações vetoriais são realizadas usando instruções como movu e paddb.
  • A função modifica os dados dos argumentos e não retorna valor.

1 comentários

 
GN⁺ 2025-02-23
Comentários no Hacker News
  • Há outro material sobre o mesmo tema nos casos do FFmpeg e do dav1d

    • O FFmpeg é usado com frequência, então pode ser visto como um caso de uso claro
    • O dav1d é usado nos principais navegadores e no sistema operacional Android, e um grande fator do seu sucesso é o SIMD escrito à mão
    • Parte do código do dav1d é executada trilhões de vezes por dia, então precisa rodar o mais rápido possível
    • A diferença de desempenho entre SIMD escrito à mão e SIMD gerado pelo compilador pode chegar a 50%
    • Recursos como a escola de linguagem assembly do FFmpeg são importantes para manter essas técnicas
  • Acho mais valioso usar intrinsics do que escrever assembly, mas a leitura foi muito útil

    • Usei o Compiler Explorer para entender as otimizações que o compilador faz para otimização de desempenho
  • Acho este guia excelente

    • Gostaria de ter tido este guia quando eu me interessava por baixo nível
  • Fico curioso se existe alguma "diversão" em aprender ou implementar assembly

    • Queria saber se há uma diversão como em LISP ou RISC-V, ou se é algo como COBOL, que se aprende para trabalhar com sistemas específicos
    • Não tenho motivo para usar assembly no trabalho do dia a dia, mas me pergunto se vale a pena investir tempo nisso por diversão
  • O sufixo "q" indica o tamanho do ponteiro, que em sistemas de 64 bits é 8

    • A frase parece confusa
    • "i.e" deveria ser "i.e.," e "(" deveria ser um parêntese de abertura
    • "sizeof" não retorna um ponteiro
  • Elogio à referência K&R

    • Foi o primeiro livro que comprei para aprender C e programação
    • No começo aprendi C++, mas era abstrato demais e difícil de entender
  • A desvantagem de usar assembly é que o código fica dependente da arquitetura

    • É preciso escrever código diferente para x86, arm e x86_64
    • Não há uma boa forma de escrever código portável para SIMD
    • O Rust está estabilizando uma API SIMD portável, e o Zig oferece suporte a SIMD, mas o FFmpeg ainda pode continuar insatisfeito com a velocidade
  • A oposição a assembly inline é confusa

    • Parece que assembly inline seria mais eficiente do que chamar uma função em assembly
  • Este material é perfeito

    • Eu conhecia assembly x86 da época do 386, mas os processadores mais avançados eram complexos demais
    • Quero aprender mais sobre SIMD nas CPUs recentes
  • Fico curioso se ainda é verdade que assembly é 10 vezes mais rápido que C

    • Será que os compiladores estagnaram a ponto de não conseguirem se aproximar de assembly escrito à mão?