11.4.3.2.5 : Abstractions d'ordre supérieur


L'écriture de code parallèle en manipulant directement des threads et des primitives de synchronisation bas niveau comme celles de PThread étant difficile, des modèles de programmation plus haut niveau simplifiant l'écriture de certaines catégories de programme ont été mis au point.

OpenMP[64]The OpenMP API specification for parallel programming, The OpenMP Team est une solution couramment utilisée en calcul intensif, qui se base sur des directives de compilation C/++ et Fortran standardisées. En sus d'offrir une abstraction des primitives du système d'exploitation, elle ajoute également une palette d'outils simplifiant grandement l'écriture et la validation de programmes parallèles composés de boucles for sur de grands tableaux d'éléments indépendants.

Toutefois, cette solution n'est pas proposée par tous les compilateurs, la qualité des implémentations varie grandement d'un compilateur à l'autre, et le vocabulaire d'abstraction ne permet pas facilement d'utiliser d'OpenMP sur des programmes plus complexes, manipulant des structures de données contenant des pointeurs par exemple. De plus, comme OpenMP n'utilise pas des constructions standard du langage hôte, son utilisation rend certaines activités comme la méta-programmation relativement délicate.

Comme approche alternative, on peut également mentionner Intel Threading Building Blocks[65]Threading Building Blocks, Intel, dont le nom est souvent abrégé en "TBB", et qui est une bibliothèque C++ qui permet de rendre le parallélisme de threads plus composable.

En effet, dans la plupart des autres approches du parallélisme, une boucle parallèle dans une boucle parallèle est une mauvaise nouvelle, car elle signifie que $n^2$ threads seront créés au lieu de $n$ , ce qui a un impact négatif sur les performances et l'utilisation des ressources. Ce problème complique souvent l'utilisation de bibliothèques de calculs écrites par des auteurs différents, qui ne peuvent se coordonner sur la question de la création des threads.

TBB règle ce problème en fournissant à l'ensemble de l'application un service commun d'exécution parallèle. Quand plusieurs bibliothèques utilisent TBB, elles se coordonnent automatiquement pour exécuter leurs tâches sur les mêmes threads partagés, et l'on reste donc dans une configuration optimale à un thread par cœur CPU.

En dehors de ça, cette bibliothèque fournit une boucle for parallèle analogue à celle d'OpenMP, diverses primitives de synchronisation, et d'autres mécanismes plus obscurs comme un moyen d'exécuter en parallèle des graphes de tâches simples.

Comme TBB est une bibliothèque, elle a l'avantage sur OpenMP de fonctionner de façon homogène sur tous les compilateurs C++ courants. En revanche, elle ne bénéficie pas d'une intégration au sein du compilateur, et ne peut donc pas offrir une assistance au programmeur qui cherche à contrôler les accès concurrents à ses variables comme OpenMP le fait.

C++17[149]C++ language reference standardise une version parallèle des algorithmes de la STL. Dans le cas de GCC et Clang, celle-ci est basée sur TBB. Ceci étend les capacités de TBB à toutes sortes de manipulation parallèle de conteneurs sur ces compilateurs, lorsque l'utilisation de C++17 et d'un compilateur récent est possible.

Avec cette évolution, C++ rejoindra la grande famille des langages de programmation disposant depuis quelque temps de fonctionnalités similaires (Rust, Java, Scala, C\#... ), soit en standard, soit via des bibliothèques matures et largement reconnues dans leurs communautés. En C++20, l'ergonomie de l'itération de collection en C++ devrait également enfin devenir comparable à celle des autres langages, grâce à l'introduction du concept de range.