Normalement, c'est au système d'exploitation de décider quels processeurs ou cœurs de la machine seront utilisés pour exécuter une application. En fonction du nombre de threads requis par l'application à un moment donné et des besoins des autres applications, le système d'exploitation tentera de déplacer les threads selon les besoins afin de maintenir la charge globale de chaque processeur équilibrée. Lorsqu'il y a plus de threads que de processeurs (ce qui est la norme), le système d'exploitation partagera les processeurs entre plusieurs threads, ce qui signifie que les threads seront mis en pause jusqu'à ce que ce soit leur tour. Pour certaines applications, cette méthode peut ne pas fonctionner correctement, et il peut être utile de dédier certains processeurs ou groupes de processeurs à des applications spécifiques. La plupart des plates-formes de systèmes d'exploitation offrent la possibilité de spécifier qu'un processus ne doit s'exécuter que sur des processeurs spécifiques. Cela s'appelle communément l'affinité CPU ou le pinning CPU.

Dédier des processeurs spécifiques à votre application peut être un moyen de garantir qu'elle disposera toujours de suffisamment de ressources CPU. Au contraire, vous pourriez explicitement laisser certains processeurs inutilisés afin de garantir des ressources suffisantes pour les autres processus s'exécutant sur la même machine. Définir l'affinité processeur peut également optimiser considérablement le cache CPU. En d'autres termes, chaque fois qu'un processus change de processeur, ses données sont transférées d'un processeur à un autre. Ce transfert est coûteux, mais vous pouvez le minimiser en épinglant le processus à un nombre limité de processeurs. Vous devez toutefois veiller à allouer suffisamment de processeurs à votre application, car elle peut avoir la capacité d'exécuter des tâches en parallèle sur différents processeurs lorsqu'ils sont disponibles.

Malheureusement, Java ne fournit pas de solution pour lancer la JVM avec une affinité de cœur ou de processeur. Si vous souhaitez épingler votre application Java à des processeurs spécifiques, vous devriez soit utiliser des commandes comme procaff, taskset, soit invoquer du code natif. Affinité processeur Ces solutions sont spécifiques à la plate-forme.

Solution

L'édition Professional du Java Service Wrapper résout ce problème en fournissant un moyen unifié et simple de configurer l'affinité CPU sans avoir à écrire de code. À partir de la version 3.5.27, seuls Windows et Linux sont pris en charge, mais la prise en charge de plates-formes supplémentaires arrivera dans les prochaines versions.

La configuration peut cibler le processus Wrapper ainsi que le processus JVM qu'il contrôle. Chacun possède ses propres propriétés pour configurer l'affinité processeur, mais si vous ne spécifiez que celles du Wrapper, par défaut le processus JVM contrôlé héritera de la même configuration et s'exécutera automatiquement en utilisant le(s) même(s) processeur(s) que le processus Wrapper.

Aperçu technique

Comment configurer l'affinité CPU pour le Wrapper

Compatibilité :3.5.27
Éditions :Édition ProfessionnelleÉdition Standard (non prise en charge)Édition Community (non prise en charge)
Plateformes :WindowsMac OSX (Non pris en charge)LinuxAlpine Linux (Non pris en charge)FreeBSD (Non pris en charge)Solaris (Non pris en charge)IBM z/Linux

Les propriétés utilisées pour configurer l'affinité processeur du processus Wrapper sont décrites ci-dessous :

Par exemple, si vous souhaitez que le Wrapper s'exécute uniquement sur les processeurs numéro 1 et 2, vous pouvez écrire l'ensemble de propriétés suivant dans votre fichier de configuration (wrapper.conf) :

Exemple
wrapper.cpu_affinity.set=TRUE
wrapper.cpu_affinity.default=FALSE
wrapper.cpu_affinity.1=TRUE
wrapper.cpu_affinity.2=TRUE

Au contraire, si vous souhaitez que le Wrapper s'exécute sur tous les processeurs sauf les numéros 1 et 2, vous pouvez écrire ce qui suit :

Exemple
wrapper.cpu_affinity.set=TRUE
wrapper.cpu_affinity.default=TRUE
wrapper.cpu_affinity.1=FALSE
wrapper.cpu_affinity.2=FALSE

Comment configurer l'affinité CPU pour le processus JVM

Compatibilité :3.5.27
Éditions :Édition ProfessionnelleÉdition Standard (non prise en charge)Édition Community (non prise en charge)
Plateformes :WindowsMac OSX (Non pris en charge)LinuxAlpine Linux (Non pris en charge)FreeBSD (Non pris en charge)Solaris (Non pris en charge)IBM z/Linux

Les exemples précédents devraient suffire dans la plupart des cas, car votre application Java et tous ses processus et threads enfants hériteront automatiquement de la même configuration et s'exécuteront sur les mêmes processeurs. Si vous souhaitez toutefois spécifier des configurations d'affinité CPU différentes pour le Wrapper et le processus qu'il contrôle, cela est possible en utilisant l'ensemble de propriétés suivant.

Vous pouvez utiliser ces propriétés de la même manière que précédemment.

Exemple 1 (autoriser la JVM à s'exécuter uniquement sur les processeurs numéro 1 et 2)
wrapper.cpu_affinity.set=TRUE
wrapper.java.cpu_affinity.default=FALSE
wrapper.java.cpu_affinity.1=TRUE
wrapper.java.cpu_affinity.2=TRUE
Exemple 2 (autoriser la JVM à s'exécuter sur tous les processeurs sauf les numéros 1 et 2)
wrapper.cpu_affinity.set=TRUE
wrapper.java.cpu_affinity.default=TRUE
wrapper.java.cpu_affinity.1=FALSE
wrapper.java.cpu_affinity.2=FALSE

Vérifier que l'affinité CPU fonctionne

Dans l'exemple précédent, vous avez peut-être remarqué que le premier processeur était désigné par l'index 1, le deuxième processeur par l'index 2, et ainsi de suite. Si vous vérifiez l'utilisation du processeur sur votre système, le premier processeur peut parfois être attribué avec l'index 0 et d'autres fois avec l'index 1. Lors de la configuration du Wrapper, le premier processeur sera toujours désigné par l'index 1.

Pour afficher l'utilisation du processeur sous Windows, ouvrez le Gestionnaire des tâches, sélectionnez l'onglet Performances, puis cliquez avec le bouton droit sur le panneau principal et, dans le menu contextuel, sélectionnez Modifier le graphique pour Processeurs logiques. Si vous avez configuré votre application pour qu'elle s'exécute uniquement sur les processeurs numéro 1 et 2, cela devrait ressembler à ceci :


Utilisation des processeurs sous Windows (Gestionnaire des tâches)

Pour afficher l'utilisation du processeur sous Linux, vous pouvez utiliser la commande top dans votre terminal et appuyer sur 1 pour voir les détails des processeurs logiques.

Sous Ubuntu, vous pouvez ouvrir le Moniteur système si vous préférez voir l'utilisation du processeur dans une fenêtre graphique :


Utilisation des processeurs sous Ubuntu (Moniteur système)