Comment les cœurs de processeur sont-ils distribués à chaque noyau dans le calcul de parallélisation?

Aug 16 2020

Je veux juste m'assurer de bien comprendre avant de poser des questions. J'ai vu des gens dire que certaines fonctions de Mathematica utiliseraient automatiquement des multi-cœurs (je ne fais pas référence à ceux que nous parallélisons, mais je me réfère à ceux comme NIntegrate), donc je pense que si j'ai 2 cœurs, ce sera plus rapide qu'un simple coeur. Donc, ma question est de savoir si j'ai un code comme celui-ci:ParallelTable[NIntegrate[x, {x, 1, 3}], {loop, 1, 3}]

Je pense que trois noyaux seront lancés. Si j'ai 4 cœurs, comment ces quatre cœurs sont-ils distribués à chaque noyau? (Puisque je pense que chaque noyau peut utiliser des multi-cœurs basés sur la propriété d'intégration de fonctions)

Réponses

4 AndreasLauschke Aug 16 2020 at 23:03

Bienvenue noo-b, m.se est une grande communauté pour un apprentissage infini sur M!

Je pense que vous avez quelques fausses hypothèses:

Premièrement, même les opérations à un seul thread peuvent s'exécuter sur plusieurs cœurs. Un bon système d'exploitation essaie d'éviter cela, mais toutes les secondes, il peut basculer vers un autre cœur, ou il peut répartir la charge sur plusieurs cœurs - bien que ces derniers ne soient généralement pas pendant une période prolongée.

Deuxièmement, vous ne pouvez pas supposer que NIntegrate sera toujours parallélisé pour toutes les entrées, et en particulier vous ne pouvez pas supposer que NIntegrate effectuera une parallélisation pendant tout le temps de calcul. Il peut être parallélisé uniquement pour l'initialisation ou à la fin, ou à certaines tâches intermédiaires. Par exemple,

Do[Do[NIntegrate[x,{x,1,3}],{3}],{100000}]

si vous regardez l'utilisation du cœur (pas: l'utilisation des processus, comme dans un simple gestionnaire de tâches) - si vous êtes sous Linux, vous pouvez exécuter top et appuyer sur 1 - vous verrez que cela passe 99% du temps sur un noyau. Il peut changer le noyau après un certain temps, mais vous voyez alors 99% pour ce noyau. Je ne vois donc pas du tout de thread NIntegrate sur plusieurs cœurs, du moins pas tout le temps (peut-être pendant des fractions de secondes). Cela peut être différent pour différentes entrées NIntegrate, mais cet exemple simple montre que NIntegrate ne parallélise pas toujours et pas pendant toute la durée de son calcul.

Avec le cadre de parallélisme M, cela ne change pas, c'est vraiment une question de système d'exploitation. Avec ParallelTable (et mes frères), vous ne faites que fournir des tâches de traitement à partir de plus de processus, et la façon dont les o / s planifient cela aux cœurs dépend entièrement du o / s. Donc, vous ne pouvez pas vraiment "annuler" l'affectation aux cœurs d'une compréhension des processus parallèles.

quelque peu tangente:

Dans Scala, Java ou C # (ou de nombreux autres langages), vous pouvez planifier des tâches au niveau d'un thread. Mais même dans ce cas, il appartient au service d'exploitation de planifier les bandes de roulement vers les noyaux. Avec vmstat de Java, vous avez une merveilleuse visualisation des threads (barres horizontales qui grandissent avec le temps, une par thread), je pense que ce qui vous intéresse vraiment, c'est comment les choses fonctionnent dans les threads, pas nécessairement comment les threads sont affectés aux cœurs . Cela dit, les threads sont un concept logiciel, pas un concept matériel, un noyau ne sait pas ce qu'est un thread. Mais je pense qu'une analyse des threads vous en dirait plus pour comprendre la concurrence comme l'affectation aux cœurs, et la commutation des cœurs, et les pourcentages de charge de travail pour chaque cœur, dépendent entièrement des o / s.

4 Szabolcs Aug 16 2020 at 23:51

Certaines fonctions utilisent automatiquement plusieurs cœurs. Le nombre de cœurs qu'ils utilisent est déterminé par certains des paramètres de SystemOptions["ParallelOptions"].

Si vous utilisez de telles fonctions sur des sous-noyaux, elles n'utiliseront qu'un seul noyau. Vous pouvez le vérifier en regardant ParallelEvaluate@SystemOptions["ParallelOptions"]. Notez que tous les nombres de threads sont définis sur 1 sur les sous-noyaux.

Généralement, la parallélisation explicite (telle que ParallelTable) n'est pas aussi efficace que la parallélisation intégrée de certaines fonctions. Ainsi, si votre goulot d'étranglement est une fonction qui s'exécute déjà en parallèle, l'implémentation d'une parallélisation supplémentaire avec ParallelTableou des fonctions associées la ralentira (ou du moins elle l'a ralentie dans tous les cas que j'ai vérifiés).