2010-07-13 26 views
8

He leído una entrada de blog hace un tiempo reclamando una aplicación Java funcionó mejor cuando se le permitió utilizar una única CPU en una máquina de múltiples núcleos: http://mailinator.blogspot.com/2010/02/how-i-sped-up-my-server-by-factor-of-6.htmlJVM en múltiples núcleos

¿Qué razones puede haber para una aplicación Java , que se ejecuta en máquinas multinúcleo para funcionar mucho más lento que en una máquina de núcleo único?

+0

Existen enlaces bastante prometedores para [Java, rendimiento y multinúcleo] (http://www.google.com/search?q=java+performance+multi+core). ¿Podría dejar una nota si esta entrada de blog está en la lista? –

Respuesta

8

Si existe una disputa significativa entre los recursos compartidos en los diferentes subprocesos, podría ser que bloquear y desbloquear objetos requiera una gran cantidad de IPI (interrupciones entre procesadores) y los procesadores pueden perder más tiempo descartando sus cachés L1 y L2 y recuperar datos de otras CPU de lo que realmente gastan haciendo progresos para resolver el problema.

Esto puede ser un problema si la aplicación tiene el modo too-fine-grained locking. (Una vez lo escuché resumir "no tiene sentido tener más de un bloqueo por línea de caché de la CPU", lo cual es definitivamente cierto, y tal vez demasiado detallado.)

Java "todos los objetos son un mutex" podría conducir a tener demasiados bloqueos en el sistema en ejecución si hay demasiados en vivo y disputados.

No tengo dudas de que alguien podría escribir intencionalmente tal aplicación, pero probablemente no sea muy común. La mayoría de los desarrolladores escriben sus aplicaciones para reducir la contención de recursos donde pueden.

+0

Esto está ignorando [la ley de Amdahl] (http://en.wikipedia.org/wiki/Amdahl%27s_law) y [la ley de Little] (http://en.wikipedia.org/wiki/Little%27s_law) que básicamente hierven hasta: algunas cosas no se dividen muy bien en tareas paralelas, independientemente del idioma/entorno. –

1

Dudo que la parte "mucho".

Supongo que el gasto de mover el estado de una CPU a otra es lo suficientemente alto como para ser notable. En general, quiere que los trabajos permanezcan en la misma CPU, por lo que sus datos se almacenan en caché tanto como sea posible localmente.

1

Esto es completamente especulativo sin el artículo/datos en cuestión, pero hay algunos tipos de programas que no son adecuados para la paralelización; quizás la aplicación nunca esté unida a la CPU (lo que significa que la CPU no es el cuello de botella, tal vez tipo de E/S es).

Sin embargo, esta pregunta/conversación es bastante infundada sin más detalles.

1

No hay una razón específica de Java para esto, pero mover el estado desde el núcleo al núcleo o incluso desde la CPU a la CPU lleva tiempo. Este tiempo se puede utilizar mejor si el proceso se mantiene en un solo núcleo. Además, el almacenamiento en caché se puede mejorar en tales casos.

Esto solo es relevante, sin embargo, si el programa no utiliza múltiples hilos y puede así distribuir su trabajo en múltiples núcleos/CPU de manera efectiva.

0

CPU Intel recientes tienen Turbo Boost:

http://en.wikipedia.org/wiki/Intel_Turbo_Boost

+0

Eso, en el peor de los casos, significaría que un programador de tareas verdaderamente absurdo (si no malicioso) podría tratar de arreglar las cosas para que Turbo Boost no se active, y ni siquiera estoy seguro de que realmente pueda ser manipulado de esa manera. En cualquier caso, nunca equivaldría a una diferencia de rendimiento de 6x. –

+1

Estoy de acuerdo. Turbo Boost ni siquiera se acerca a 6x. – Puppy

0

Ésta será depende del número de hilos desova la aplicación. Si engendras, digamos cuatro hilos de trabajo haciendo un gran número de crujidos, la aplicación será casi cuatro veces más rápida en una máquina de cuatro núcleos, dependiendo de la cantidad de contabilidad y fusión que debes hacer.

1

La aplicación podría hacer un uso muy pobre de bloquear la comunicación entre hilos. Sin embargo, esto se debe únicamente al hecho de que la aplicación está programada excepcionalmente pobremente.

No hay ninguna razón para que una aplicación multi-core, incluso mediocremente programada, con una carga de trabajo moderadamente paralela, se ejecute más lentamente en múltiples núcleos.

1

Desde una perspectiva de rendimiento puro, el desafío suele ser el subsistema de memoria. Entonces, aunque más CPUs a menudo son buenas, tener CPU que no estén cerca de la memoria en la que se encuentran los objetos de Java es muy, muy costosa. Es MUY específico de la máquina y depende en gran medida de la ruta exacta entre cada CPU y memoria. Tanto Intel como AMD han tenido varias formas/velocidades aquí, y los resultados varían mucho.

Consulte NUMA por las razones por las cuales los núcleos múltiples pueden dificultar.

Hemos visto los deltas de rendimiento en el rango del 30% o más, según cómo se anclan las JVM a los procesadores. SPECjbb2005 ahora se ejecuta principalmente en modo "multi-JVM" con cada JVM asociada con una CPU/memoria determinada por este motivo.

0

CPU a menudo tienen un límite de la cantidad de calor que pueden producir. Esto significa que un chip con menos núcleo puede ejecutarse a una alta frecuencia, lo que puede hacer que un programa funcione más rápido si no utiliza el núcleo extra de manera efectiva. Hoy la diferencia es entre 4, 6 y 8 núcleos, donde más núcleos son individualmente más lentos. No conozco ningún sistema central único que sea más rápido que el sistema de 4 núcleos más rápido.

+0

En el artículo, el autor aceleró su servidor al asignarlo a una sola CPU en lugar de 6 – IttayD

+0

Tiene razón al asignar todos sus procesos a un núcleo. Si esto funciona, es casi seguro que tiene un problema de ajuste, aunque no está claro qué es. –

1

El JIT no incluirá barreras de memoria si cree que se está ejecutando en un solo núcleo. Sospecho que eso es lo que está sucediendo en el artículo al que se hace referencia.

Aquí es una explicación muy concisa de barreras de memoria, sino que también proporciona una técnica limpia de ver el código JIT'd: http://www.infoq.com/articles/memory_barriers_jvm_concurrency

Esto no quiere decir que todas las aplicaciones se beneficiarían de ser colocado en una sola núcleo.

Cuestiones relacionadas