tiempo que online justo incrementales ejecutar ejecución computacion compiladores compilación compila codigo java jit compiler-optimization

que - jit java



(¿Cómo) el compilador JIT de Java optimiza mi código? (4)

Estoy escribiendo un código de nivel bastante bajo que debe ser altamente optimizado para la velocidad. Cada ciclo de CPU cuenta. Dado que el código está en Java, no puedo escribir un nivel tan bajo como en C, por ejemplo, pero quiero sacar todo lo que pueda de la VM.

Estoy procesando una matriz de bytes. Hay dos partes de mi código que me interesan principalmente en este momento. El primero es:

int key = (data[i] & 0xff) | ((data[i + 1] & 0xff) << 8) | ((data[i + 2] & 0xff) << 16) | ((data[i + 3] & 0xff) << 24);

y el segundo es:

key = (key << 15) | (key >>> 17);

A juzgar por el rendimiento, supongo que estas afirmaciones no están optimizadas de la forma que esperaba. La segunda afirmación es básicamente una ROTL 15, key . La primera instrucción carga 4 bytes en un int. Las máscaras 0xff están ahí solo para compensar los bits de signo agregados resultantes de la conversión implícita a int si el byte accedido es negativo. Esto debería ser fácil de traducir a un código de máquina eficiente, pero para mi sorpresa, el rendimiento aumenta si me quito las máscaras. (Lo que por supuesto rompe mi código, pero estaba interesado en ver qué pasa).

¿Que está pasando aqui? ¿Las máquinas virtuales Java más comunes optimizan este código durante el JIT de la manera que uno esperaría que un buen compilador de C ++ optimice el código equivalente de C ++? ¿Puedo influir en este proceso? Establecer -XX:+AggressiveOpts parece no hacer ninguna diferencia.

(CPU: x64, Plataforma: Linux / HotSpot)



Estoy de acuerdo con solendil, pero si desea profundizar en el nivel bajo, intente obtener el código producido por el JIT como se describe here .


He hecho un montón de código de rendimiento en Java, incluso he codificado directamente en Bytecode, lo suficiente para estar seguro de un par de cosas: el JIT es una caja negra con comportamientos oscuros, el JIT y los compiladores son increíblemente eficientes, y El código más simple por lo general produce el mejor rendimiento.

Esto es normal cuando piensa en la META del JIT: extraiga el mejor rendimiento posible de cualquier código Java. Cuando agrega que Java es un lenguaje sencillo y sencillo, el código simple se optimizará y cualquier otro truco generalmente no servirá de nada.

Por supuesto, hay algunas trampas y errores comunes que debe conocer, pero no veo ninguno en sus ejemplos de código. Si yo fuera para optimizar su código, iría directamente al nivel superior: algoritmo. ¿Cuál es la complejidad de su código? ¿Se pueden almacenar algunos datos en caché? ¿Qué APIs se utilizan? Etc ... Hay un pozo de rendimiento aparentemente interminable que se puede extraer de los trucos algorítmicos solo.

Y si incluso esto no es suficiente, si el lenguaje no es lo suficientemente rápido, si su máquina no es lo suficientemente rápida, si su algoritmo no puede acelerarse, la respuesta no estará en "ciclos de reloj", ya que podría oprimir 20 % de eficiencia, pero un 20% nunca será suficiente cuando sus datos crezcan. Para asegurarse de que nunca volverá a alcanzar (nuevamente) un muro de rendimiento, la respuesta definitiva está en la escalabilidad: haga que su algoritmo y sus datos se distribuyan sin cesar, de modo que pueda dedicar más trabajadores a la tarea.


No es necesario (y 0xff) antes de desplazar 24 bits a la izquierda.