web-dev-qa-db-fra.com

Comment programmer l'allocation des threads sur les processeurs multicœurs?

Je voudrais expérimenter avec des threads sur un processeur multicœur, par ex. pour créer un programme qui utilise deux threads différents qui sont exécutés par deux cœurs de processeur différents.

Cependant, il n'est pas clair pour moi à quel niveau les threads sont alloués aux différents cœurs. Je peux imaginer les scénarios suivants (selon le système d'exploitation et l'implémentation du langage de programmation):

  1. L'allocation des threads est gérée par le système d'exploitation. Les threads sont créés à l'aide d'appels système du système d'exploitation et, si le processus s'exécute sur un processeur multicœur, le système d'exploitation essaie automatiquement d'allouer/planifier différents threads sur différents cœurs.
  2. L'allocation des threads est gérée par l'implémentation du langage de programmation. L'allocation de threads à différents cœurs nécessite des appels système spéciaux, mais les bibliothèques de threads standard du langage de programmation gèrent automatiquement cela lorsque j'utilise l'implémentation de thread standard pour ce langage.
  3. L'allocation des threads doit être programmée explicitement. Dans mon programme, je dois écrire du code explicite pour détecter le nombre de cœurs disponibles et allouer différents threads à différents cœurs en utilisant, par exemple, les fonctions de bibliothèque.

Pour rendre la question plus précise, imaginez que j'ai écrit mon application multithread en Java ou C++ sur Windows ou Linux. processeur (car tout est géré soit par le système d'exploitation, soit par la bibliothèque de threads standard), ou dois-je modifier mon code pour être conscient des multiples cœurs?

13
Giorgio

Mon application verra-t-elle et utilisera-t-elle plusieurs cœurs comme par magie lorsqu'elle est exécutée sur un processeur multicœur (car tout est géré soit par le système d'exploitation, soit par la bibliothèque de threads standard), ou dois-je modifier mon code pour connaître les cœurs multiples ?

Réponse simple: Oui, il sera généralement géré par le système d'exploitation ou la bibliothèque de threads.

Le sous-système de threading du système d'exploitation attribuera des threads aux processeurs en priorité (votre option 1). En d'autres termes, lorsqu'un thread a terminé son exécution pour son allocation de temps ou ses blocs, le planificateur recherche le prochain thread de priorité la plus élevée et l'affecte à la CPU. Les détails varient d'un système d'exploitation à l'autre.

Cela dit, les options 2 (gérées par le langage de programmation) et 3 (explicitement) existent. Par exemple, la bibliothèque de tâches et async/wait dans les versions récentes de .Net offrent au développeur un moyen beaucoup plus facile d'écrire du code parallélisable (c'est-à-dire qui peut s'exécuter simultanément avec lui-même). Les langages de programmation fonctionnels sont intrinsèquement parallélisables et certains runtimes exécuteront différentes parties du programme en parallèle si possible.

Comme pour l'option 3 (explicitement), Windows vous permet de définir l'affinité du thread (en spécifiant sur quels processeurs un thread peut s'exécuter). Cependant, cela n'est généralement pas nécessaire dans tous les systèmes critiques, à l'exception des plus rapides. L'allocation efficace du thread au processeur dépend fortement du matériel et est très sensible aux autres applications s'exécutant simultanément.

Si vous voulez expérimenter, créez une tâche longue et gourmande en ressources processeur, comme générer une liste de nombres premiers ou créer un ensemble Mandelbrot. Créez maintenant deux threads dans votre bibliothèque préférée et exécutez les deux threads sur une machine multiprocesseur (en d'autres termes, à peu près tout ce qui a été publié ces dernières années). Les deux tâches doivent se terminer à peu près en même temps car elles sont exécutées en parallèle.

11
akton