El artículo técnico explora la viabilidad de escribir intérpretes de máquina virtual en ensamblador para superar el rendimiento de los compiladores modernos, un tema que suele ser objeto de rumores en la comunidad de programación. El autor, Matt Keeter, analiza su implementación de un intérprete rápido para la CPU Uxn, una arquitectura de pila con 256 instrucciones, comparando el código generado por el compilador con la versión optimizada en ensamblador.
El análisis revela que, aunque el compilador logra una mejora del 10-20% sobre la implementación de referencia mediante la monomorfización y la inserción de instrucciones, el código generado presenta ineficiencias críticas. Específicamente, el compilador almacena valores críticos, como los índices de pila y las direcciones base de memoria, en la memoria en lugar de en registros, lo que obliga a realizar cargas adicionales. Además, el bucle de despacho utiliza una rama indirecta única, lo que genera una alta imprevisibilidad en la ejecución y consume más del tercio del tiempo total en las instrucciones más calientes.
Para resolver esto, el autor propone una estrategia de asignación de registros donde se almacenan todos los datos importantes en registros para evitar cargas superfluas. Este enfoque, inspirado en la arquitectura de LuaJIT, permite mantener el estado en registros y reducir la complejidad de las ramas indirectas. El texto detalla cómo esta optimización en ensamblador es necesaria para lograr el máximo rendimiento en intérpretes, ya que los compiladores no pueden generar con fiabilidad los patrones de registro y ramificación extremadamente específicos requeridos para la máxima velocidad.
