Question

Erlang est connu pour sa capacité à prendre en charge de nombreux processus légers. cela est possible car ce ne sont pas des processus au sens traditionnel du terme, ni même des threads comme dans les P-threads, mais des threads entièrement dans l’espace utilisateur.

C'est bien beau (fantastique en fait). Mais comment alors les threads Erlang sont-ils exécutés en parallèle dans un environnement multicœurs / multi-processeurs? Ils doivent sûrement être mappés sur les threads du noyau pour être exécutés sur des cœurs séparés.

En supposant que ce soit le cas, comment cela se fait-il? De nombreux processus légers sont-ils mappés sur un seul thread de noyau?

Ou existe-t-il un autre moyen de contourner ce problème?

Était-ce utile?

La solution

La réponse dépend de la machine virtuelle utilisée:

1) non-SMP : il existe un planificateur (thread OS), qui exécute tous les processus Erlang, issus du pool des processus exécutables (c.-à-d. ceux qui ne sont pas bloqués, par exemple, reçoivent )

2) SMP : Il existe K ordonnanceurs (les threads du système d'exploitation, K étant généralement un nombre de cœurs de processeur), qui exécutent les processus Erlang à partir du processus partagé. file d'attente . C'est une simple file d'attente FIFO (avec des verrous pour permettre l'accès simultané à partir de plusieurs threads du système d'exploitation).

3) SMP dans R13B et plus récent : il y aura K ordonnanceurs (comme auparavant) qui exécute les processus Erlang à partir de files d'attente de processus . Chaque planificateur a sa propre file d'attente. Par conséquent, la logique de migration d'un planificateur à un autre sera ajoutée. Cette solution améliorera les performances en évitant un verrouillage excessif de la file d'attente de processus partagée.

Pour plus d'informations, voir ce document préparé par Kenneth Lundin, Ericsson AB, pour la conférence des utilisateurs Erlang, Stockholm, le 13 novembre 2008.

Autres conseils

Je veux modifier les réponses précédentes.

Erlang, ou plutôt le système d'exécution Erlang (erts), définit par défaut le nombre de planificateurs (threads OS) et le nombre de files d'attente au nombre d'éléments de traitement sur votre plate-forme. Il s’agit de cœurs de processeurs ou de threads matériels. Vous pouvez modifier ces paramètres au moment de l'exécution à l'aide de:

erlang:system_flag(schedulers_online, NP) -> PrevNP

Les processus Erlang n’ont encore aucune affinité avec les planificateurs. La logique d'équilibrage des processus entre les ordonnanceurs suit deux règles. 1) Un ordonnanceur affamé volera le travail d'un autre ordonnanceur. 2) Les chemins de migration sont configurés pour transférer les processus des planificateurs comportant de nombreux processus à des planificateurs nécessitant moins de travail. Ceci est fait pour assurer l’équité du nombre de réductions (temps d’exécution) pour chaque processus.

Les planificateurs peuvent toutefois être verrouillés à des éléments de traitement spécifiques. Ce n'est pas fait par défaut. Pour que les erts fassent le planificateur -> utiliser l’affinité principale:

erlang:system_flag(scheduler_bind_type, default_bind) -> PrevBind

Plusieurs autres types de liens peuvent être trouvés dans la documentation. L'utilisation de l'affinité peut grandement améliorer les performances dans les situations de charge lourde! Surtout dans les situations de conflit de verrouillage élevé. En outre, le noyau Linux ne peut pas gérer les hyperthreads pour le moins. Si vous avez des hyperthreads sur votre plate-forme, vous devriez vraiment utiliser cette fonctionnalité dans erlang.

Je ne fais que deviner, mais j'imagine qu'il existe un petit nombre de threads, qui sélectionnent des processus d'exécution dans un pool de processus commun. Lorsqu'un processus atteint une opération de blocage, le thread qui l'exécute le met de côté et en sélectionne un autre. Lorsqu'un processus en cours d'exécution provoque le déblocage d'un autre processus, ce processus nouvellement débloqué est placé dans le pool. Je suppose qu'un thread peut également arrêter l'exécution d'un processus même s'il n'est pas bloqué à certains moments pour servir d'autres processus.

J'aimerais ajouter des éléments à ce qui a été décrit dans la réponse acceptée.

Erlang Scheduler est la partie essentielle du système d'exécution Erlang et fournit sa propre abstraction et implémentation de la conception de processus légers au sommet des threads du système d'exploitation.

Chaque planificateur s'exécute dans un seul thread de système d'exploitation. Normalement, il y a autant de programmateurs que de processeurs (cœurs) sur le matériel (il est configurable et n'apporte naturellement pas beaucoup de valeur lorsque le nombre de programmateurs dépasse celui des cœurs de matériel). Le système peut également être configuré pour que le planificateur ne bascule pas entre les unités d'exécution du système d'exploitation.

Maintenant, lors de la création du processus Erlang, il incombe entièrement à ERTS et au planificateur de gérer le cycle de vie, la consommation de ressources, ainsi que son empreinte mémoire, etc.

L’un des principaux détails de la mise en œuvre est que chaque processus dispose d’un budget de temps de 2 000 réductions disponibles lorsque le planificateur relève ce processus dans la file d’exécution. Chaque progrès dans le système (même les E / S) est garanti d'avoir un budget de réduction. C’est ce qui fait du système ERTS un système multitâche préemptif.

Je recommanderais un excellent billet de blog sur ce sujet de Jesper Louis Andersen http://jlouisramblings.blogspot.com/2013/01/how-erlang-does-scheduling.html

Comme réponse courte: les processus Erlang ne sont pas des threads de système d’exploitation et ne mappent pas directement sur eux. Erlang Schedulers est ce qui fonctionne sur les threads du système d’exploitation et offre une implémentation intelligente de processus Erlang plus détaillés masquant ces détails derrière les yeux du programmeur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top