11.4.3.2.3 : Abstractions d'exécution parallèle


L'abstraction principale fournie par le système d'exploitation pour permettre le calcul multi-cœur est le thread. Un processus en cours d'exécution peut créer autant de threads qu'il le souhaite, et le système d'exploitation se chargera d'organiser l'exécution de ceux-ci sur les différentes ressources de calcul disponible noteParfois, la logique d'ordonnancement par défaut du système d'exploitation n'est pas optimale. Dans ce cas, le programme peut le guider en lui indiquant la meilleure répartition des threads sur les ressources d'exécution disponibles..

Sous les systèmes POSIX, comme Linux, l'API système principale pour créer et gérer des threads est PThread[66]Threading Building Blocks, Open Group. Comme beaucoup d'APIs POSIX, sa standardisation a malheureusement été un échec partiel, car son comportement varie tellement d'une implémentation à l'autre qu'il n'est pas vraiment possible de l'utiliser pour programmer plusieurs systèmes de façon portable. Par conséquent, lorsqu'une portabilité entre systèmes d'exploitation est désirée, on devra avoir recours à une couche d'abstraction.

Celle-ci est souvent fournie directement par la bibliothèque standard du langage de programmation utilisé, à condition toutefois que celui-ci supporte pleinement les threads. En effet, le support des threads compliquant l'implémentation, tous les langages de programmation ne supportent pas leur utilisation, et ceux qui le supportent ne permettent pas forcément leur exécution simultanée. Ainsi le langage Python par exemple permet de créer plusieurs tâches, mais pas de les exécuter simultanément.

Lorsque c'est le cas, une technique de contournement consiste à lancer $n$ copies du programme, chacune tournant dans son propre processus système. Mais cette technique possède un grand nombre d'inconvénients~:



Quand on met tout cela bout à bout, la programmation d'un calcul multi-processus devient souvent aussi complexe que celle d'un calcul distribué, avec les mêmes difficultés de passage à l'échelle, et rend très difficile l'exploitation efficace de la mémoire partagée qui est l'élément central du parallélisme multi-cœur.

Par conséquent, les langages de programmation ne permettant pas l'utilisation de threads pour le parallélisme doivent être évités autant que faire se peut, et quand on n'a pas le choix ils doivent être interfacés à d'autres langages qui n'ont pas cette limitation pour tirer au mieux parti du parallélisme intra-nœud.