2010-02-10 10 views
56

¿Alguien sabe de una forma de bloquear subprocesos individuales dentro de un proceso de Java a núcleos de CPU específicos (en Linux)? He hecho esto en C, pero no puedo encontrar cómo hacerlo en Java. Mi instinto es que esto requerirá una llamada JNI, pero esperaba que alguien aquí pudiera tener alguna idea o podría haberlo hecho antes.Afinidad de subprocesos de Java

Gracias!

+1

Ver mi respuesta a continuación a los comentarios de Hassan. Algunos hilos son muy intensivos en E/S, otros son intensivos en CPU. Si estoy protegiendo las interrupciones de E/S en un núcleo particular, me gustaría que los subprocesos intensivos de E/S estuvieran en núcleos en el mismo socket, y me gustaría proteger los hilos intensivos de CPU de la E/S. . – Dave

+40

@gimpf: como siempre con este tipo de "preguntas cuestionadas": SO no se trata del "por qué", se trata del "cómo". La afinidad de CPU existe por alguna razón, hay una razón por la cual hay utilidades tanto en Linux como en Windows para establecer la afinidad de la CPU de un proceso. La pregunta del OP es una pregunta perfectamente válida que no quiere "por qué" sino un "cómo". – SyntaxT3rr0r

+6

@WizardOfOdds: dudo que el "por qué" esté prohibido en SO, y como Java no suele ser el primer lenguaje de programación para los ajustes de rendimiento relacionados con la concurrencia, creo que un chequeo de cordura es válido. – gimpf

Respuesta

42

No se puede hacer esto en Java puro. Pero si realmente lo necesita, puede usar JNI para llamar al código nativo que hace el trabajo. Este es el lugar para comenzar con:

http://ovatman.blogspot.com/2010/02/using-java-jni-to-set-thread-affinity.html

http://blog.toadhead.net/index.php/2011/01/22/cputhread-affinity-in-java/

UPD: Después de pensarlo, he decidido crear mi propia clase para esto: ThreadAffinity.java Es basa-JNA, y muy simple, entonces, si desea usarlo en producción, puede que deba dedicar algún tiempo a hacerlo más estable, pero para la evaluación comparativa y las pruebas funciona bien tal como está.

UPD 2: Hay otra library para trabajar con afinidad de hilos en java. Utiliza mismo método como se ha señalado anteriormente, pero tiene otra interfaz

+0

+1 ¡Funciona! ¡Increíble! Tenga en cuenta el comentario que dejé en el primer blog: necesita '#define _GNU_SOURCE' sobre todos los includes. –

+1

+1: He convertido esta funcionalidad en una biblioteca que usa JNI o ​​JNA, dependiendo de lo que esté disponible. También tiene un temporizador de baja latencia y admite la espera ocupada con la instrucción PAUSE asm. https://github.com/peter-lawrey/Java-Thread-Affinity –

+0

@PeterLawrey Eso es genial, gracias! (suponiendo que funcione y aún no lo he verificado). Sin embargo, hay algunos problemas con su biblioteca (principalmente documentación y un error); ¿Cómo puedo contactarte sobre eso? – Raphael

0

IMO, no será posible a menos que use llamadas nativas. Se supone que JVM es independiente de la plataforma, cualquier llamada al sistema realizada para lograr esto no generará un código portátil.

+6

No me preocupa la portabilidad. – Dave

+5

@questzen: ¿y si la llamada al sistema se realiza solo si se encuentra que el programa Java se ejecuta en un sistema operativo que admite dicha llamada? El código aún sería portátil, pero simplemente no establecería ninguna afinidad de CPU en otros sistemas operativos. Esta es la única cosa que siempre me rompe: personas gritando "código no portátil" tan pronto como haces algo de JNI o ​​Runtime.exec(). Tengo un programa que hace las dos cosas y funciona en Linux, Windows y OS X. – SyntaxT3rr0r

+0

No se trata de usar o no las llamadas nativas, sino de si la plataforma admite esto "de fábrica". @questzen tiene razón en que la JVM no tendrá acceso abstracto a esto porque no es muy neutral en cuanto a la plataforma. Es posible que pueda encontrar bibliotecas de terceros que lo hagan. – PSpeed

0

No es posible (al menos con Java simple).

Puede usar thread pools para limitar la cantidad de hilos (y, por lo tanto, núcleos) utilizados para diferentes tipos de trabajo, pero no hay forma de especificar un núcleo para usar.

Existe incluso la (pequeña) posibilidad de que el tiempo de ejecución de Java no sea compatible con el enhebrado nativo para su SO o hardware. En este caso, se utilizan green threads y solo se utilizará un núcleo para toda la JVM.

9

Sé que ha pasado un tiempo, pero si alguien se encuentra con este hilo, así es como he resuelto este problema. Escribí un guión que hacer lo siguiente:

  1. "jstack -l"
  2. tomar los resultados, encontrar el "NID" 's de los hilos que quiero bloquear manualmente hacia abajo para núcleos.
  3. Taskset esos hilos.
+1

Fuera de interés, pensé que el conjunto de tareas solo funcionaba en procesos, no en hilos individuales. ¿Cuál es la sintaxis para hacerlo a un hilo? – Matt

Cuestiones relacionadas