Apple integra el compilador LLVM para mejorar el rendimiento de WebKit JavaScript

Apple integra el compilador LLVM para mejorar el rendimiento de WebKit JavaScript

La semana pasada analizamos algunas de las cosas que pueden influir en la velocidad de los lenguajes de programación y cómo los diferentes enfoques de la ejecución del código pueden afectar el rendimiento del programa. Parte del trabajo que Apple describe esta semana muestra cómo las técnicas comunes a un idioma se pueden aplicar a otro.

Los navegadores modernos utilizan un esquema llamado compilación justo a tiempo para convertir JavaScript en código ejecutable y lograr un alto rendimiento al hacerlo. A medida que el proceso de optimización se hizo más avanzado y el rendimiento mejoró, los desarrolladores de WebKit de Apple se dieron cuenta de que estaban construyendo más y más de las mismas capacidades que ya tenían los desarrolladores de compiladores tradicionales. Sintiendo que esto es un desperdicio, decidieron dejar de crear los suyos propios y aprovechar las capacidades de optimización del compilador LLVM.

El trabajo se describió a principios de esta semana en una publicación de blog. Anteriormente, el motor JavaScript de WebKit tenía tres etapas diferentes que lograban diferentes niveles de rendimiento para los scripts que ejecutaban. La primera etapa fue un intérprete que ejecutaba programas script sin compilarlos. Esto permite que los scripts se ejecuten «instantáneamente» sin tener que esperar a un compilador.

Si una función de JavaScript se llama más de seis veces o se repite más de 100 veces, pasa al siguiente paso: un compilador JIT básico que produce código ejecutable. No optimiza en gran medida, pero elimina parte de la sobrecarga que el intérprete tiene que producir código unas diez veces más rápido que el intérprete.

Si luego se llama a la función más de 66 veces o se repite más de 1000 veces, se alimenta a la tercera etapa, un compilador JIT que en realidad dedica un tiempo relativamente largo a optimizar el código. La salida de la tercera etapa es unas tres veces más rápida que el JIT básico, o 30 veces más rápida que el intérprete. Llevaría mucho tiempo optimizar todos funcione con este compilador, razón por la cual se utiliza este enfoque paso a paso.

Aunque este tercer paso es mucho más rápido que el intérprete, todavía no coincide con un compilador típico de C o C++ para optimizaciones de bajo nivel: determinar qué valores almacenar en qué registros, por ejemplo. Los desarrolladores de WebKit querían agregar un cuarto paso para hacer este tipo de trabajo, pero aunque pensaron que escribirlo desde cero sería «súper divertido», también sería mucho trabajo. Mucho trabajo que ya hacen los compiladores C y C++ existentes. Por lo tanto, decidieron investigar el uso de la generación y optimización de código LLVM.

Publicidad

El cuarto nivel basado en LLVM se llama FTL, por LLVM de cuarto nivel (y, por supuesto, Más rapido que la luz). Comparte algunas partes con la tercera etapa, ya que la tercera etapa ya hace un trabajo importante al manejar la naturaleza dinámica de JavaScript, pero tiene una parte de generación de código diferente.

El resultado es una mejora saludable en el rendimiento. FTL produce código más de 40 veces más rápido que el intérprete, y los puntos de referencia tardan aproximadamente un tercio menos en ejecutarse que el antiguo sistema de tres niveles.

Una de las desventajas del compilador LLVM es que es relativamente lento. Esto no es del todo sorprendente, ya que LLVM está diseñado para optimizar bien, en lugar de optimizar rápidamente, y para una compilación avanzada del tipo utilizado para C y C++, vale la pena tomarse el tiempo adicional para hacer un buen trabajo. Para manejar esto, WebKit solo usa FTL para funciones que tardan mucho tiempo en ejecutarse (10 milisegundos) o se llaman mucho, para asegurarse de que realmente vale la pena usar FTL, luego ejecuta FTL en un subproceso de fondo. No necesita esperar a que finalice ese subproceso, ya que, mientras tanto, solo puede usar el código del paso tres.

FTL está actualmente disponible en compilaciones nocturnas de WebKit y está habilitado de forma predeterminada.

Hace diez años, JavaScript era solo un lenguaje interpretado y, por eso, era bastante lento. Desde entonces, ha crecido en prominencia y se ha sometido a considerables esfuerzos de desarrollo para mejorar su rendimiento. El uso de LLVM y la integración de un optimizador de compilador tradicional muestran cómo las características comunes a un conjunto de lenguajes pueden usarse en otros, desdibujando las distinciones entre diferentes tipos de lenguaje.

Es poco probable que Apple sea el único desarrollador de navegadores que haga este tipo de cosas. A los desarrolladores de navegadores les encanta presumir del rendimiento de sus motores de JavaScript, y Microsoft y Google no permitirán que Apple tome la delantera en esta área.

Imagen de listado por webkit.org

Deja un comentario

Tu dirección de correo electrónico no será publicada.