Le permite vincular un hilo a un núcleo determinado, esto puede mejorar el rendimiento (esta biblioteca funciona mejor en Linux).
Biblioteca OpenHFT Java Thread Affinity
Consulte affinity/src/test/java para ver ejemplos prácticos de cómo utilizar esta biblioteca.
V3.2.0: agregue soporte para la configuración de texto
V3.1.1: dependencia JNA actualizada a 4.4.0
V2.0.1: se agregó getThreadId para el proceso del hilo.
Java-Thread-Affinity intentará utilizar JNA para proporcionar acceso a funciones nativas de manejo de subprocesos. JNA debe estar instalado en su sistema para aprovechar al máximo esta biblioteca.
Java-Thread-Affinity actualmente depende de la versión 4.4.0 de JNA, que a su vez depende de una versión de GLIBC >= 2.14. Si su sistema operativo es antiguo, con una versión de GLIBC lanzada antes de 2011, esta biblioteca no podrá invocar funciones nativas.
Para solucionar este problema, bifurque el repositorio y anule la etiqueta <version>
para los artefactos jna
y jna-platform
en el archivo pom
del proyecto.
sudo apt-get instalar libjna-java
sudo yum instalar jna
La biblioteca leerá su /proc/cpuinfo
si tiene uno o si proporciona uno y determinará el diseño de su CPU. Si no tiene uno, asumirá que cada CPU está en un zócalo de CPU.
La biblioteca busca CPU aisladas determinadas observando las CPU en las que no se está ejecutando de forma predeterminada. es decir, si tiene 16 CPU pero 8 de ellas no están disponibles para uso general (según lo determinado por la afinidad del proceso al inicio), comenzará a asignarse a esas CPU.
Nota: si tiene más de un proceso usando esta biblioteca, debe especificar qué CPU puede usar el proceso; de lo contrario, asignará las mismas CPU a ambos procesos. Para controlar qué CPU puede usar un proceso, agregue -Daffinity.reserved={cpu-mask-in-hex} a la línea de comando del proceso.
Nota: la CPU 0 está reservada para el Sistema Operativo, tiene que ejecutarse en algún lugar.
https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started
https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/How-it-works
http://vanillajava.blogspot.co.uk/2013/07/micro-jitter-busy-waiting-and-binding.html
Java-Thread-Affinity requiere que primero aísle algunas CPU.
Una vez que se aísla un núcleo de CPU, el programador de Linux no utilizará el núcleo de la CPU para ejecutar ningún proceso en el espacio de usuario. Las CPU aisladas no participarán en el equilibrio de carga y no tendrán tareas ejecutándose en ellas a menos que se les asigne explícitamente.
Para aislar el primer y tercer núcleo de CPU (los números de CPU comienzan desde 0) en su sistema, agregue lo siguiente a la línea de comando del kernel durante el arranque:
isolcpus=1,3
Puedes adquirir un bloqueo para una CPU de la siguiente manera:
En Java 6
AffinityLock al = AffinityLock . acquireLock ();
try {
// do some work locked to a CPU.
} finally {
al . release ();
}
En Java 7 u 8
try ( AffinityLock al = AffinityLock . acquireLock ()) {
// do some work while locked to a CPU.
}
Tienes más opciones como
Puedes reservar un núcleo entero. Si tiene habilitado Hyper-Threading, esto usará una CPU y dejará su CPU gemela sin usar.
try ( AffinityLock al = AffinityLock . acquireCore ()) {
// do some work while locked to a CPU.
}
Puede elegir un diseño relativo a un candado existente.
try ( final AffinityLock al = AffinityLock . acquireLock ()) {
System . out . println ( "Main locked" );
Thread t = new Thread ( new Runnable () {
@ Override
public void run () {
try ( AffinityLock al2 = al . acquireLock ( AffinityStrategies . SAME_SOCKET ,
AffinityStrategies . ANY )) {
System . out . println ( "Thread-0 locked" );
}
}
});
t . start ();
}
En este ejemplo, la biblioteca preferirá una CPU libre en el mismo socket que el primer subproceso; de lo contrario, elegirá cualquier CPU libre.
Puede obtener la identificación del hilo actual usando
int threadId = AffinitySupport . getThreadId ();
Puede obtener la CPU actual que está utilizando
int cpuId = AffinitySupport . getCpu ();
La afinidad del proceso al inicio es
long baseAffinity = AffinityLock . BASE_AFFINITY ;
La CPU disponible para la reserva es
long reservedAffinity = AffinityLock . RESERVED_AFFINITY ;
Si desea obtener/establecer la afinidad directamente, puede hacerlo
long currentAffinity = AffinitySupport . getAffinity ();
AffinitySupport . setAffinity ( 1L << 5 ); // lock to CPU 5.
Para obtener una vista detallada del estado de afinidad actual (como lo ve la biblioteca), ejecute el siguiente script en sistemas Linux:
# change to the affinity lock-file directory (defaults to system property java.io.tmpdir)
$ cd /tmp
# dump affinity state
$ for i in "$(ls cpu-*)";
do PID="$(cat $i | head -n1)"; TIMESTAMP="$(cat $i | tail -n1)";
echo "pid $PID locked at $TIMESTAMP in $i"; taskset -cp $PID;
cat "/proc/$PID/cmdline"; echo; echo
done
pid 14584 locked at 2017.10.30 at 10:33:24 GMT in cpu-3.lock
pid 14584's current affinity list: 3
/opt/jdk1.8.0_141/bin/java ...
Grupo de soporte de afinidad de subprocesos de Java
Para ver un artículo sobre la diferencia que puede hacer la afinidad y cómo usarla http://vanillajava.blogspot.com/2013/07/micro-jitter-busy-waiting-and-binding.html
Actualmente estoy trabajando en un proyecto relacionado con la detección de interbloqueos en programas multiproceso en java. Estamos intentando ejecutar subprocesos en diferentes procesadores y, por lo tanto, encontramos sus publicaciones de github sobre el mismo. https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started Siendo principiante, tengo pocos conocimientos y, por lo tanto, necesito su ayuda. Necesitamos saber cómo ejecutar subprocesos en un número de CPU específico y luego cambiar de subproceso cuando uno está esperando.
// lock a cpuId
try ( AffinityLock lock = AffinityLock . acquireLock ( n )) {
}
donde n es la CPU en la que desea ejecutar el hilo.
O
// lock one of the last CPUs
try ( AffinityLock lock = AffinityLock . acquireLockLastMinus ( n )) {
}
Tengo el cpuId en un archivo de configuración, ¿cómo puedo configurarlo usando una cadena?
try ( AffinityLock lock = AffinityLock . acquireLock ( "last" )) {
assertEquals ( PROCESSORS - 1 , Affinity . getCpu ());
}
try ( AffinityLock lock = AffinityLock . acquireLock ( "last-1" )) {
assertEquals ( PROCESSORS - 2 , Affinity . getCpu ());
}
try ( AffinityLock lock = AffinityLock . acquireLock ( "1" )) {
assertEquals ( 1 , Affinity . getCpu ());
}
try ( AffinityLock lock = AffinityLock . acquireLock ( "any" )) {
assertTrue ( lock . bound );
}
try ( AffinityLock lock = AffinityLock . acquireLock ( "none" )) {
assertFalse ( lock . bound );
}
try ( AffinityLock lock = AffinityLock . acquireLock (( String ) null )) {
assertFalse ( lock . bound );
}
try ( AffinityLock lock = AffinityLock . acquireLock ( "0" )) { // prints a warning
assertFalse ( lock . bound );
}