Le protagoniste d'aujourd'hui est une question d'extension (question) de la question polyvalente du modèle GMP dans l'interview de Go, c'est-à-dire "Modèle GMP, pourquoi a-t-il besoin de P?"
Plonger davantage dans l'arrière-plan de la question, en fait, cette interview L'essence de la question est de demander : «Dans le modèle GMP, pourquoi G et M ne peuvent-ils pas être directement liés ? essayer de résoudre ?"
Cet article vous amènera à explorer les raisons des changements dans les modèles GM et GMP.static void schedule(G *gp) { ... schedlock(); if(gp != nil) { ... switch(gp->status){ case Grunnable: case Gdead: // Shouldn't have been running! runtime·throw("bad gp->status in sched"); case Grunning: gp->status = Grunnable; gput(gp); break; } gp = nextgandunlock(); gp->readyonstop = 0; gp->status = Grunning; m->curg = gp; gp->m = m; ... runtime·gogo(&gp->sched, 0); }
schedlock
méthode pour obtenir Verrouillage global.
schedlock
方法来获取全局锁。
gput
方法来保存当前 Goroutine 的运行状态等信息,以便于后续的使用。
nextgandunlock
方法来寻找下一个可运行 Goroutine,并且释放全局锁给其他调度使用。
runtime·gogo
nextgandunlock
méthode pour trouver Le prochain Goroutine peut être exécuté et le verrou global est libéré pour que d'autres planificateurs puissent l'utiliser.
Appelméthode runtime·gogo
, exécutez le prochain Goroutine à exécuter qui vient d'être obtenu et entrez dans le prochain cycle de planification.
En analysant le code source du planificateur de Go1.0.1, nous pouvons trouver un point intéressant. Il s'agit du planificateur lui-même (méthode de planification). Dans les processus normaux, il ne reviendra pas, c'est-à-dire qu'il ne mettra pas fin au processus principal.
Diagramme du modèle G-M Il exécutera en continu le processus de planification une fois que GoroutineA est terminé, il commence à rechercher GoroutineB. Lorsque B est trouvé, le droit de planification terminé de A est transmis à B, de sorte que GoroutineB. commence à être Scheduling, c'est-à-dire en cours d'exécution. Bien sûr, il y a aussi des G qui sont bloqués (Blocked). Supposons que G effectue des appels système ou réseau, ce qui entraînera le blocage de G. À ce moment-là, M (thread système) sera remis dans la file d'attente du noyau, en attendant un nouveau cycle de réveil. Inconvénients du modèle GMEn apparence, le modèle GM semble indestructible et sans défauts. Mais pourquoi le changer ? En 2012, Dmitry Vyukov a publié l'article "Scalable Go Scheduler Design Doc", qui est toujours la cible principale des principaux articles de recherche sur le planificateur Go. Il a décrit les raisons et considérations générales dans l'article. Le contenu suivant citera cet article. .Le planificateur Goroutine actuel (faisant référence au modèle GM de Go 1.0) limite l'évolutivité des programmes concurrents écrits en Go, en particulier les serveurs à haut débit et les programmes de calcul parallèle.
L'implémentation présente les problèmes suivants :
Afin de résoudre bon nombre des problèmes ci-dessus du modèle GM, dans Go1.1, Dmitry Vyukov a ajouté un nouveau composant P (processeur) basé sur le modèle GM. Et implémenté l'algorithme Work Stealing pour résoudre certains problèmes nouvellement générés.
Modèle GMP, dans l'article précédent « Les amis du groupe Go ont demandé : quel est le nombre approprié de Goroutines à contrôler, cela affectera-t-il le GC et la planification ? a été expliqué dans "."
Les amis qui pensent que c'est bien peuvent y prêter attention, je ne le répéterai pas ici.
Quels changements cela apportera-t-il après l'ajout de P ? Parlons-en plus explicitement.
Chaque P a sa propre file d'attente locale, ce qui réduit considérablement la dépendance directe à l'égard de la file d'attente globale. Le résultat est une réduction de la concurrence entre les verrous. La majeure partie des performances supplémentaires du modèle GM est due à la concurrence des verrous.
Sur l'équilibre relatif de chaque P, l'algorithme Work Stealing est également implémenté dans le modèle GMP. Si la file d'attente locale de P est vide, l'exécutable G sera volé dans la file d'attente globale ou la file d'attente locale de. d'autres P à fonctionner, réduisant ainsi la marche au ralenti et améliorant l'utilisation des ressources.
Certains amis peuvent être confus en ce moment Si vous souhaitez implémenter une file d'attente locale et un algorithme de vol de travail, alorspourquoi ne pas simplement l'ajouter directement à M ? pour M Des fonctions similaires peuvent être obtenues.
Pourquoi ajouter un autre composant P ?
Combiné avec le positionnement de M (thread système), si vous faites cela, il y a les problèmes suivants.
D'une manière générale, le nombre de M sera supérieur à celui de P. Comme dans Go, la limite maximale du nombre de M est de 10 000 et le nombre par défaut de P est le nombre de cœurs de processeur. De plus, en raison des propriétés de M, c'est-à-dire que s'il existe un appel de blocage du système qui bloque M et n'est pas suffisant, M continuera d'augmenter.
Si M continue d'augmenter, si la file d'attente locale est montée sur M, cela signifie que la file d'attente locale augmentera également en conséquence. Ceci est évidemment déraisonnable, car la gestion des files d’attente locales deviendra compliquée et les performances du Work Stealing seront considérablement réduites.
M Après avoir été bloqué par un appel système, nous espérons allouer ses tâches non exécutées à d'autres pour continuer à s'exécuter, plutôt que de tout arrêter dès qu'il est bloqué.
Par conséquent, il n'est pas raisonnable d'utiliser M. Ensuite, introduire un nouveau composant P et associer la file d'attente locale à P peut très bien résoudre ce problème.
L'article d'aujourd'hui combine quelques situations historiques, une analyse des causes et une description de la solution pour l'ensemble du planificateur de langage Go.
« Modèle GMP, pourquoi y a-t-il P ? » Cette question est comme une compréhension de la conception d'un système, car désormais de nombreuses personnes vont mémoriser le modèle GMP ou le parcourir de manière instantanée afin de faire face à l'entretien. Et comprendre les véritables raisons qui en sont la cause est ce que nous devons apprendre et comprendre.
Ce n'est que lorsque vous savez ce qui se passe et pourquoi cela se produit que vous pourrez briser la situation.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!