2016-12-30 2 views
1

Quelqu'un peut-il m'aider à comprendre comment la JVM répartit les threads entre les cœurs de processeurs disponibles? Voici ma vision de la façon dont cela fonctionne mais pls corrigez-moi. Dès le début: lorsque l'ordinateur est démarré, le processus d'amorçage (généralement le thread 0 dans le cœur 0 du processeur 0) lance le chargement du code à partir de l'adresse 0xfffffff0. Tous les autres processeurs/cœurs sont dans un état de veille spécial appelé Wait-for-SIPI (WFS). Puis, après le chargement de l'OS, il commence à gérer les processus et à les programmer entre les CPU/coeurs envoyant une IPI (Inter-Processor Interrupteur) spéciale sur le contrôleur d'interruption programmable (APIC) appelé SIPI (Startup IPI). c'est dans WFS. Le SIPI contient l'adresse à partir de laquelle ce thread doit commencer à récupérer le code. Par exemple, OS a démarré JVM en chargeant du code JVM en mémoire et en pointant l'un des cœurs du CPU vers son adresse (en utilisant le mécanisme décrit ci-dessus). Après cela, la machine virtuelle Java exécutée en tant que processus de système d'exploitation distinct avec sa propre zone de mémoire virtuelle peut démarrer plusieurs threads.Comment la JVM répartit les threads entre les cœurs du processeur?

La question est: comment?

JVM utilise-t-il le même mécanisme que le système d'exploitation et pendant la tranche de temps que le système d'exploitation a donné à la JVM peut envoyer SIPI à d'autres cœurs et pointer l'adresse des tâches à exécuter dans un thread séparé? Si oui alors comment est restauré le programme original qui pourrait être exécuté par OS sur ce noyau? Supposons que ce n'est pas une vision correcte car supposons que cette tâche impliquant d'autres processeurs/cœurs devrait être gérée via le système d'exploitation. Au-delà, nous pourrions interrompre l'exécution de certains processus OS fonctionnant en parallèle sur d'autres cœurs. Donc, si JVM veut lancer un nouveau thread sur un autre CPU/core, il fait un appel au système d'exploitation et envoie l'adresse de la tâche à exécuter au système d'exploitation. OS plan d'exécution comme pour les autres programmes mais avec des différences que cette exécution devrait se produire dans le même processus pour pouvoir accéder au même espace d'adressage que les autres threads JVM.

Comment cela se fait-il? Quelqu'un peut-il le décrire en plus de détails?

+1

La JVM est un processus ordinaire. Il (et ses threads) sont gérés par le système d'exploitation/noyau, y compris la création et la planification. Tout comme tous les autres processus et threads. La partie que vous mettez en gras n'a rien de spécial non plus - c'est comme ça que fonctionnent tous les threads habituels. – Mat

+0

et pouvons-nous manipuler à partir de la machine virtuelle Java quel processeur et quel noyau doivent être utilisés pour certains threads ou sont-ils entièrement sous le contrôle du système d'exploitation? – user3342955

+1

Ceci est spécifique à la plate-forme. Si vous êtes correct avec l'écriture de code natif, dans Linux, la programmation manuelle est faite par l'appel système 'sched_setaffinity'. À ma connaissance, il n'y a pas d'encapsuleur Java dans la bibliothèque standard. Regardez aussi la commande 'taskset' pour exécuter toute la JVM avec une affinité modifiée. – gudok

Répondre

5

Le système d'exploitation gère et programme les threads par défaut. La JVM fait les bons appels à l'OS pour y arriver, mais ne s'implique pas.

Est-ce que JVM utilise le même mécanisme que OS

La machine virtuelle Java utilise le système d'exploitation, il n'a aucune idée de ce qui se passe réellement. Chaque processus a son propre espace d'adressage virtuel, encore une fois géré par le système d'exploitation.

J'ai une bibliothèque qui utilise JNA pour emballer setaffinity sur Linux et Windows. Vous devez le faire car la programmation des threads est contrôlée par le système d'exploitation et non par la JVM.

https://github.com/OpenHFT/Java-Thread-Affinity

Note: dans la plupart des cas, à l'aide d'affinité soit a) ne contribue pas ou b) ne contribue pas autant que vous pourriez penser. Nous l'utilisons pour réduire la gigue d'environ 40 à 100 microsecondes ce qui n'arrive pas souvent, mais assez souvent pour influencer notre profil de performance. Si vous voulez que vos latences à 99% soient aussi faibles que possible, dans la gamme des micro-secondes, l'affinité du fil est essentielle.Si vous êtes d'accord avec 1 sur 100 demandes prenant 1 ms de plus, je ne voudrais pas déranger.