2 puntos por GN⁺ 2025-02-23 | 1 comentarios | Compartir por WhatsApp

Introducción

  • Bienvenido a la clase de lenguaje ensamblador de FFmpeg. Esta clase ofrece una base sobre cómo se escribe lenguaje ensamblador en FFmpeg.

Conocimientos necesarios

  • Se requiere conocimiento del lenguaje C, especialmente sobre punteros.
  • Se requiere conocimiento de matemáticas de nivel preparatoria/secundaria superior (escalares y vectores, suma, multiplicación, etc.).

¿Qué es el lenguaje ensamblador?

  • El lenguaje ensamblador es un lenguaje de programación con el que se escribe código que corresponde directamente a las instrucciones que procesa la CPU.
  • La mayor parte del código en ensamblador de FFmpeg es SIMD (Single Instruction Multiple Data), lo que también se conoce como programación vectorial.
  • SIMD es adecuado para procesar grandes cantidades de datos almacenados secuencialmente en memoria, como imágenes, video y audio.

¿Por qué escribirlo en lenguaje ensamblador?

  • Para acelerar la velocidad del procesamiento multimedia. Al escribir código en ensamblador, se puede obtener una mejora de velocidad de más de 10 veces.
  • En FFmpeg se escribe ensamblador directamente sin usar intrinsics. Los intrinsics suelen ser entre 10 y 15% más lentos que el ensamblador hecho a mano.

Tipos de lenguaje ensamblador

  • Esta clase se centra en el lenguaje ensamblador x86 de 64 bits. También se conoce como amd64 y funciona igualmente en CPUs Intel.
  • En la sintaxis de ensamblador x86 hay dos variantes, AT&T e Intel, y se usará la sintaxis Intel.

Material de apoyo

  • La programación en ensamblador de FFmpeg se enfoca en el procesamiento de imágenes de alto rendimiento y tiene un enfoque particular.
  • Los diagramas del libro "The Art of 64-bit assembly" pueden ser de ayuda.

Registros

  • Los registros son áreas dentro de la CPU donde se procesan los datos. La CPU no manipula la memoria directamente, sino que carga los datos en registros, los procesa y luego los vuelve a escribir en memoria.

Registros de propósito general

  • Los registros de propósito general (GPR) pueden contener datos o direcciones de memoria. En el código ensamblador de FFmpeg, los GPR funcionan principalmente como apoyo.

Registros vectoriales

  • Los registros vectoriales (SIMD) contienen múltiples elementos de datos. Existen varios tipos de registros vectoriales.
  • La mayoría de los cálculos de compresión y descompresión de video se basan en enteros.

Inclusión de x86inc.asm

  • x86inc.asm es una capa de abstracción ligera utilizada en FFmpeg, x264 y dav1d para facilitar el trabajo de los programadores de ensamblador.

Código ensamblador escalar sencillo

  • Se explica cómo funciona el código ensamblador escalar a través de un ejemplo.

Entender una función vectorial básica

  • A través del primer ejemplo de una función SIMD, se explica el significado de cada línea.
  • Se usan instrucciones como movu y paddb para realizar operaciones vectoriales.
  • La función modifica los datos de sus argumentos y no devuelve ningún valor.

1 comentarios

 
GN⁺ 2025-02-23
Opiniones de Hacker News
  • Hay otro material sobre el mismo tema en los casos de FFmpeg y dav1d

    • FFmpeg se usa con frecuencia, así que puede verse como un caso de uso claro
    • dav1d se usa en los principales navegadores y en el sistema operativo Android, y un factor importante de su éxito es el SIMD escrito a mano
    • Parte del código de dav1d se ejecuta billones de veces al día, así que debe correr lo más rápido posible
    • La diferencia de rendimiento entre SIMD escrito a mano y SIMD generado por el compilador puede llegar hasta el 50%
    • Recursos como la escuela de lenguaje ensamblador de FFmpeg son importantes para mantener estas técnicas
  • Creo que usar intrínsecos tiene más valor que escribir ensamblador, pero fue muy útil leer esto

    • Usé Compiler Explorer para entender las optimizaciones que hace el compilador para mejorar el rendimiento
  • Creo que esta guía es excelente

    • Ojalá hubiera tenido esta guía cuando me interesaba el bajo nivel
  • Me pregunto si hay algún "placer" en aprender o implementar ensamblador

    • Me pregunto si tiene algo de diversión como LISP o RISC-V, o si es más como COBOL, que se aprende para trabajar con sistemas específicos
    • No tengo motivos para usar ensamblador en mi trabajo diario, pero me pregunto si vale la pena invertir tiempo por diversión
  • El sufijo "q" indica el tamaño del puntero, y en sistemas de 64 bits es 8

    • La frase se siente confusa
    • "i.e" debería ser "i.e.,", y "(" debería ser un paréntesis de apertura
    • "sizeof" no devuelve un puntero
  • Elogio a la referencia de K&R

    • Fue el primer libro que compré para aprender C y programación
    • Al principio aprendí C++, pero era demasiado abstracto y difícil de entender
  • La desventaja de usar ensamblador es que el código depende de la arquitectura

    • Hay que escribir código distinto para x86, arm y x86_64
    • No hay una buena manera de escribir código portable para SIMD
    • Rust está estabilizando una API SIMD portable, y Zig ofrece soporte SIMD, pero FFmpeg probablemente seguiría inconforme con la velocidad
  • Me confunde la oposición al ensamblador en línea

    • Parece que el ensamblador en línea sería más eficiente que llamar a una función en ensamblador
  • Este material es perfecto

    • Conocía el ensamblador x86 de la época del 386, pero los procesadores más avanzados eran demasiado complejos
    • Quiero aprender más sobre SIMD en CPUs recientes
  • Me pregunto si todavía es cierto que el ensamblador es 10 veces más rápido que C

    • Me pregunto si los compiladores se han estancado tanto como para no poder acercarse al ensamblador escrito a mano