¿El JIT actual optimiza los códigos de máquina generados para la predicción de sucursal en función de las estadísticas de tiempo de ejecución?

8

Algunas JVM compilarían código de bytes de Java en código de máquina nativo. Sabemos que hay muchas optimizaciones que podríamos aplicar para eso. Recientemente, también me enteré de que una operación de bifurcación puede bloquear la CPU y afectar el rendimiento significativamente, si una CPU hace una predicción incorrecta.

¿Alguien sabe si alguna JVM generaría códigos de máquina más fáciles para la CPU haciendo predicciones correctas basadas en estadísticas de tiempo de ejecución recopiladas?

William Wong
fuente
1
Creo que HotSpot hace esto, pero también la CPU tiene tecnología de predicción dinámica desde Pentium II, por lo que si toma la decisión equivocada dos veces, se corregirá por tercera vez si se le permite reconocer el contexto.
Aadaam

Respuestas:

6

No, HotSpot no agrega sugerencias al predictor de rama de hardware como se indica en la lista de correo de OpenJDK :

Ha sido considerado y decidido en contra. Las plataformas que actualmente apuntan a openjdk tienen predicciones de ramas de hardware decentes a espectaculares. Los que no lo hicieron, como Niagara 1, ignoraron los bits de predicción. La conclusión es que no vale la pena complicar el código con, como dice David, 'macros mágicas'.

Rafael Winterhalter
fuente
OpenJDK no es HotSpot AFAIK.
Florian Margaine
Sí lo es. HotSpot es la VM que forma parte de OpenJDK: openjdk.java.net/groups/hotspot
Rafael Winterhalter
Mi mal entonces. Pensé que HotSpot era la VM de Sun, y OpenJDK era una alternativa de código abierto.
Florian Margaine
2

Mi conjetura es que las sugerencias de predicción en el nivel de instrucción de la máquina son, en el mejor de los casos, un ruido y, en el peor de los casos, un detrimento (bytes de instrucciones desperdiciados) en la arquitectura moderna fuera de orden y de ejecución especulativa. Hacerlo sería como decirle a la CPU que no haga nada, que deje de hacer sus cosas ya inteligentes para las que está diseñada.


En segundo lugar, el grado en que se puede mejorar la predicción de la rama depende de la causa de la predicción errónea y de la facilidad con la que se pueden medir los efectos de rendimiento u observar la tendencia de la rama.


Sin embargo, creo que la bolsa existente de trucos de optimización JIT ya puede mejorar la predicción de rama en cierta medida, incluso sin la ayuda de contadores de predicción de rama de CPU.

Solo un ejemplo de código muy simple:

public void repeatHistory(int value)
{
    if (value == 1492)
    {
        landing();
    }
    else if (value == 1776)
    {
        ratifying();
    }
}

Supongo que repeatHistoryse llama muchas veces. Cuando el monitor de rendimiento basado en muestreo analiza las estadísticas de la pila de llamadas, puede encontrar que, por cualquier razón, las repeatHistory()llamadas se ratifying()producen con más frecuencia que las llamadas anteriores landing(). Según esta observación, el próximo paso de la generación de código JIT para el repeatHistorymétodo tendrá esto en cuenta y realizará una o más optimizaciones:

  • Mueva el cheque por (value == 1776)delante del cheque por(value == 1492)
  • Intente incorporar el ratifying()método en la rama enrepeatHistory()
  • Si repeatHistory()se llama desde otro bucle, intente desenrollar el bucle o inserte el repeatHistory()método en ese bucle.
  • Y muchos otros.

Después de aplicar una optimización, a menudo es necesario analizar nuevamente para ver si se pueden aplicar más optimizaciones, porque una exitosa a menudo abrirá la puerta a más oportunidades.


rwong
fuente