java linux linux-kernel cpu javac

¿Por qué la ejecución paralela en la compilación java toma crecimiento lineal en el tiempo



linux linux-kernel (1)

time javac Main.java --> 0m1.050s time javac Main.java & javac Main.java --> 0m1.808s time javac Main.java & javac Main.java & javac Main.java --> 0m2.690s time javac Main.java & ... 8 time --> 0m8.309s

Cuando ejecutamos javac comando javac en paralelo y con cada aumento en javac comando javac se agrega ~1 sec para que se complete todo el comando javac .

¿Por qué hay un crecimiento lineal es el tiempo?

Es todo javac proceso javac mientras se ejecuta involucrado de algún tipo en locks , si es así cómo superarlo para no tener un crecimiento lineal en el tiempo

PD: He intentado anteriormente en single core machine double core machine , la double core machine 4 core machine todos mostraron el mismo comportamiento.

PS2: entorno RedHat7 , javac 1.7.0_79


El compilador de Java ya maneja la división de su trabajo entre los procesadores disponibles, incluso cuando solo compila un único archivo. Por lo tanto, ejecutar instancias de compilador separadas en paralelo no le dará las ganancias de rendimiento que espera.

Para demostrar esto, Main1.java un programa java grande (1 millón de líneas, 10.000 métodos) en un solo archivo llamado Main1.java . Luego hizo copias adicionales como Main2.java a Main8.java . Los tiempos de compilación son los siguientes:

Compilación de un solo archivo:

time javac Main1.java & --> (real) 11.6 sec

Ver este único archivo compilar en el top revelado uso del procesador en su mayoría en el rango 200-400% (que indica el uso de CPU múltiple, 100% por CPU), con picos ocasionales en el rango 700% (el máximo en esta máquina es 800% ya que hay 8 procesadores).

A continuación, dos archivos al mismo tiempo:

time javac Main1.java & --> (real) 14.5 sec time javac Main2.java & --> (real) 14.8 sec

Entonces solo tomó 14.8 segundos para compilar dos, cuando tomó 11.6 segundos para compilar uno. Eso definitivamente no es lineal. Estaba claro al mirar en la top mientras estos se ejecutaban que cada compilador de java solo estaba aprovechando como máximo cuatro CPU a la vez (con picos ocasionales más altos). Debido a esto, los dos compiladores se encontraron con ocho CPU en su mayoría en paralelo.

A continuación, cuatro archivos al mismo tiempo:

time javac Main1.java & --> (real) 24.2 sec time javac Main2.java & --> (real) 24.6 sec time javac Main3.java & --> (real) 25.0 sec time javac Main4.java & --> (real) 25.0 sec

De acuerdo, aquí hemos golpeado la pared. Ya no podemos paralelizar el compilador. Cuatro archivos tomaron 25 segundos cuando dos tomaron 14.8. Hay una pequeña optimización allí, pero es principalmente un aumento de tiempo lineal.

Finalmente, ocho simultáneamente:

time javac Main1.java & --> (real) 51.9 sec time javac Main2.java & --> (real) 52.3 sec time javac Main3.java & --> (real) 52.5 sec time javac Main4.java & --> (real) 53.0 sec time javac Main5.java & --> (real) 53.4 sec time javac Main6.java & --> (real) 53.5 sec time javac Main7.java & --> (real) 53.6 sec time javac Main8.java & --> (real) 54.6 sec

Esto fue en realidad un poco peor que lineal, ya que ocho tomaron 54.6 segundos mientras que cuatro solo tomaron 25.0.

Así que creo que la conclusión de todo esto es tener fe en que el compilador hará un trabajo decente tratando de optimizar el trabajo que le das a través de los recursos de CPU disponibles, y que intentar agregar paralelización adicional a mano tendrá limitaciones (si corresponde) beneficio.

Editar:

Como referencia, hay dos entradas que encontré en la base de datos de errores de Oracle con respecto a la mejora de javac para aprovechar los múltiples procesadores:

  • Error ID: JDK-6629150 - La queja original, esto fue marcado como un duplicado de:
  • Id. De error: JDK-6713663 : sugiere la resolución y, en función de la "Fecha resuelta", parece que el soporte de multiprocesador en javac se agregó el 2008-06-12.