Vous permet de lier un thread à un noyau donné, cela peut améliorer les performances (cette bibliothèque fonctionne mieux sous Linux).
Bibliothèque d'affinité de thread Java OpenHFT
Voir affinity/src/test/java pour des exemples pratiques d'utilisation de cette bibliothèque.
V3.2.0 - Ajout de la prise en charge de la configuration du texte
V3.1.1 - Dépendance JNA mise à niveau vers 4.4.0
V2.0.1 - Ajout de getThreadId pour le processus du thread.
Java-Thread-Affinity tentera d'utiliser JNA pour donner accès aux fonctions natives de gestion des threads. JNA doit être installé sur votre système pour tirer le meilleur parti de cette bibliothèque.
Java-Thread-Affinity dépend actuellement de la version 4.4.0 de JNA, qui à son tour dépend d'une version de GLIBC >= 2.14. Si votre système d'exploitation est ancien, avec une version de GLIBC publiée avant 2011, cette bibliothèque ne pourra pas invoquer de fonctions natives.
Pour contourner ce problème, forkez le référentiel et remplacez la balise <version>
pour les artefacts jna
et jna-platform
dans le fichier pom
du projet.
sudo apt-get install libjna-java
sudo miam installer jna
La bibliothèque lira votre /proc/cpuinfo
si vous en avez un ou en fournissez un et déterminera la disposition de votre processeur. Si vous n'en avez pas, cela supposera que chaque processeur se trouve sur un seul socket.
La bibliothèque recherche les processeurs isolés déterminés en examinant les processeurs sur lesquels vous n'exécutez pas par défaut. c'est-à-dire que si vous disposez de 16 processeurs mais que 8 d'entre eux ne sont pas disponibles pour un usage général (tel que déterminé par l'affinité du processus au démarrage), l'attribution à ces processeurs commencera.
Remarque : si plusieurs processus utilisent cette bibliothèque, vous devez spécifier quels processeurs le processus peut utiliser, sinon il attribuera les mêmes processeurs aux deux processus. Pour contrôler les processeurs qu'un processus peut utiliser, ajoutez -Daffinity.reserved={cpu-mask-in-hex} à la ligne de commande du processus.
Remarque : le CPU 0 est réservé au système d'exploitation, il doit fonctionner quelque part.
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 nécessite que vous isoliez d'abord certains processeurs.
Une fois qu'un cœur de processeur est isolé, le planificateur Linux n'utilisera pas le cœur de processeur pour exécuter des processus dans l'espace utilisateur. Les processeurs isolés ne participeront pas à l’équilibrage de charge et aucune tâche ne s’exécutera sur eux, sauf si cela leur est explicitement attribué.
Pour isoler les premier et troisième cœurs de processeur (les numéros de processeur commencent à 0) sur votre système, ajoutez ce qui suit à la ligne de commande du noyau lors du démarrage :
isolcpus=1,3
Vous pouvez acquérir un verrou pour un processeur de la manière suivante :
En Java 6
AffinityLock al = AffinityLock . acquireLock ();
try {
// do some work locked to a CPU.
} finally {
al . release ();
}
En Java 7 ou 8
try ( AffinityLock al = AffinityLock . acquireLock ()) {
// do some work while locked to a CPU.
}
Vous disposez d'autres options telles que
Vous pouvez réserver un noyau entier. Si l'hyper-threading est activé, cela utilisera un processeur et laissera son double processeur inutilisé.
try ( AffinityLock al = AffinityLock . acquireCore ()) {
// do some work while locked to a CPU.
}
Vous pouvez choisir une disposition par rapport à une serrure existante.
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 ();
}
Dans cet exemple, la bibliothèque préférera un CPU libre sur le même Socket que le premier thread, sinon elle choisira n'importe quel CPU libre.
Vous pouvez obtenir l'identifiant du fil de discussion actuel en utilisant
int threadId = AffinitySupport . getThreadId ();
Vous pouvez obtenir le processeur actuellement utilisé par
int cpuId = AffinitySupport . getCpu ();
L'affinité du processus au démarrage est
long baseAffinity = AffinityLock . BASE_AFFINITY ;
Le CPU disponible pour la réservation est
long reservedAffinity = AffinityLock . RESERVED_AFFINITY ;
Si vous souhaitez obtenir/définir l'affinité directement, vous pouvez le faire
long currentAffinity = AffinitySupport . getAffinity ();
AffinitySupport . setAffinity ( 1L << 5 ); // lock to CPU 5.
Pour une vue détaillée de l'état d'affinité actuel (tel que vu par la bibliothèque), exécutez le script suivant sur les systèmes 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 ...
Groupe de support Java Thread Affinity
Pour un article sur la différence que l'affinité peut faire et comment l'utiliser http://vanillajava.blogspot.com/2013/07/micro-jitter-busy-waiting-and-binding.html
Je travaille actuellement sur un projet lié à la détection des blocages dans les programmes multithread en Java. Nous essayons d'exécuter des threads sur différents processeurs et sommes ainsi tombés sur vos publications github à ce sujet. https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started Étant débutant, j'ai peu de connaissances et j'ai donc besoin de votre aide. Nous devons savoir comment exécuter des threads sur un numéro de processeur spécifié, puis changer de thread lorsque l'on attend.
// lock a cpuId
try ( AffinityLock lock = AffinityLock . acquireLock ( n )) {
}
où n est le processeur sur lequel vous souhaitez exécuter le thread.
OU
// lock one of the last CPUs
try ( AffinityLock lock = AffinityLock . acquireLockLastMinus ( n )) {
}
J'ai le cpuId dans un fichier de configuration, comment puis-je le définir à l'aide d'une chaîne ?
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 );
}