El proyecto FFmpeg es para muchos absolutamente desconocido, pero sus prestaciones a la hora de codificar y descodificar audio y vídeo son sencillamente prodigiosas. Tanto es así que lo usan todas las grandes tecnológicas, desde YouTube hasta Netflix o Spotify.
Ensamblador. Lo curioso es que estos días alguien ha descubierto algo sorprendente: FFmpeg puede ir hasta 94 veces más rápido, y todo gracias al uso de ensamblador, un lenguaje de programación de bajo nivel que permite acceder a los recursos del PC de forma mucho más directa en comparación a como lo hacen los lenguajes de alto nivel y los compiladores que generan código ejecutable. En DeepMind lo usaron no hace mucho para crear un algoritmo de ordenación revolucionario, y es también la base de la programación de la Voyager 1.
Vamos a probar. Un grupo de desarrolladores que contribuyen al proyecto quisieron hacer una prueba implementando ciertas funciones usando el conjunto de instrucciones AVX-512. La ventaja de estas instrucciones es que permiten procesar cadenas de datos más grandes en paralelo usando registros de 512 bits, algo que es muy útil para todo tipo de tareas, pero especialmente para procesar audio y vídeo.
Hasta 94 veces más rápido. Las pruebas de rendimiento demostraron que las funciones escritas en ensamblador con el conjunto de instrucciones AVX-512 se ejecutaban considerablemente más rápido que implementaciones tradicionales escritas en el lenguaje de programación C o conjuntos de instrucciones como AVX2 (Advanced Vector Extensions, en este caso manejando 256 bits), y las viejas SSE3 (Streaming SIMD Extension 3) de 2004. En algunos casos el código nuevo llegó a correr 94 veces más rápido que el de sus otras versiones.
Será difícil aprovechar estas mejoras. Lamentablemente, estas mejoras difícilmente llegarán a ser aprovechadas masivamente. Intel desactivó AVX-512 en sus chips porque los núcleos de alta eficiencia no las soportan, aunque hay formas de aprovecharlas desactivando esos núcleos E.
Sí están soportadas por los chips de AMD, pero el verdadero problema está en otro lado: la complejidad de dichas optimizaciones está reservada a aplicaciones muy específicas. Puede no obstante que las Big Tech hayan tomado nota y aprovechen dichas ventajas para procesar audio y vídeo en sus centros de datos.
Un lenguaje arcano pero prodigioso. Lo cierto es que el lenguaje ensamblador no es especialmente popular, y con razón. Es un lenguaje muy complejo, diferente para cada máquina/arquitectura, y es fácil cometer errores. Los lenguajes de alto nivel, los compiladores y los entornos de programación han hecho mucho más accesible estas tareas, pero lógicamente lo han hecho a costa de posibles ineficiencias. Lo que ha pasado con FFmpeg lo demuestra: hay proyectos que probablemente ganarían notables prestaciones de aprovechar la potencia del código ensamblador, y lo hacen porque como bien indican en el subreddit r/asm, con ensamblador cada byte cuenta.
En Xataka | El legendario lenguaje de programación COBOL acaba de cumplir 60 años, y es probable que cumpla otros 60 más
Ver 20 comentarios
20 comentarios
black_ice
Hoy en día esto de que todo es mas rápido si lo escribes en assembly es directamente un mito. Hace 20 años si que había una diferencia significativa, especialmente si conocías a fondo la arquitectura para la que programabas.
Las arquitecturas de CPU modernas son mucho mas complejas y tienen muchísimas optimizaciones disponibles (e.g out-of-order execution, Branch Prediction, Speculative Execution) que aceleran la ejecución de programas una barbaridad.
Para maximizar la probabilidad de que dichas optimizaciones entren en escena, el compilador, además de convertir el código humano (C/ C++ etc) a código maquina, hace otra serie de tareas como reordenar las instrucciones o loop unrolling, todo aprovechar al máximo las arquitecturas mdoernas y aprovechar su capacidad de ejecutar ciertas instrucciones en paralelo (aunque tenga un sólo núcleo y aunque el código sea estrictamente secuencial).
Aquí lo importante, y la razón del speedup, es que usaron las extensiones AVX-512 y para ello tuvieron que hacerlo en assembly. Probablemente también se podría hacer en C, pero esto depende de las APIs disponibles y probablemente optaron por hacerlo directamente en assembly solo como prueba de concepto. (No tengo experiencia usando extensiones AVX-512 o instrucciones SIMD).
juanjosvq
Desde tiempos inmemoriales diseñar un programa tirando de ensamblador era lo más rápido para ejecutarse. Al fin y al cabo le estabas dando los datos en código máquina. El ensamblador era para que aún siendo un jeroglífico fuera algo medio entendible.
Ahora, no sé en estos tiempos como se gestionan los punteros, interrupciones, el decidir cómo se usan los núcleos de un procesador. Yo me quedé en en 6502, 8085 y algo del 8086.
Si hay algún programador que quiera poner su pincelada de conocimiento, agradecido quedo. Porque a mis 56 ya me voy perdiendo.
dark_god
Los compiladores tienen funciones intrísecas para acceder a estas instrucciones de la CPU sin tirar de ensamblador. Se podría haber hecho en C/C++ perfectamente.
Gonzalo
Sería más correcto decir que un código en ensamblador hecho a medida para esta tarea es más eficiente que el código de ensamblador generado por el compilador de C de la aplicación original. Los procesadores al final solo ejecutan ensamblador. El problema principal es que los compiladores sirven para todo tipo de aplicaciones y no pueden hacer determinadas presunciones que en un código a medida si se puede.
stranno
El cuello de botella de FFMPEG, digamos al 90%, si no más, es el encoder de vídeo. Y ellos no desarrollan probablemente ninguno de los cientos de encoders de vídeo que implementan. Por ejemplo, el más popular, x264, está desarrollado por VideoLAN (los de VLC). FFMPEG no toma partido en ello, simplemente lo implementa y quizá añada pequeños parches. Más aún obviamente con todos los encoders en harware, que son creaciones de Nvidia, Intel, Apple o AMD, como CUDA/NVENC, Quick Sync o AMF.
Es decir, podrían picar las instrucciones de FFMPEG con martillo y cincel en el die del procesador, que FFMPEG no mejoraría su desempeño absolutamente nada. Lo máximo que han conseguido ha sido mejorar la paralelización de pipes en las últimas versiones de FFMPEG. Y gracias.
Donde sí hay margen de mejora es en el rendimiento de los filtros (filter_complex), pero, de nuevo, eso es una parte absolutamente ridícula del tiempo de CPU en comparación al encoder de vídeo.
Orbayo
"Tanto es así que lo usan todas las grandes tecnológicas, desde YouTube hasta Netflix o Spotify."
Y sin pagar ni un duro.