7. Threading implicite, pools et OpenMP
7.1 Déléguer la mécanique
Créer manuellement un thread pour chaque petite tâche augmente la complexité, le coût de création et le risque d’erreur. Le threading implicite confie au compilateur, à une bibliothèque ou à un environnement d’exécution une partie de la création, de l’affectation et de la destruction. Le programmeur décrit davantage le travail et moins le cycle de vie de chaque thread.
7.2 Pools de threads
Un pool crée à l’avance un nombre borné de travailleurs. Les tâches entrent dans une file; un thread libre en prend une, l’exécute, puis retourne attendre. Lorsque tous les travailleurs sont occupés, les tâches restent en file.
Avantages :
- amortir le coût de création et de destruction;
- diminuer la latence de traitement des requêtes courtes;
- borner le nombre de piles et la pression sur le noyau;
- séparer le code métier de la politique d’exécution.
Le dimensionnement reste un compromis. Un pool trop petit laisse le matériel inutilisé et allonge la file; un pool trop grand augmente la contention, la mémoire occupée et les changements de contexte.
7.3 OpenMP
OpenMP ajoute à C/C++ des directives pour la mémoire partagée. Une région simple peut être indiquée ainsi :
Code (c) · sélectionner pour copier
#pragma omp parallel
{
/* travail exécuté par une équipe de threads */
}
D’autres directives répartissent les itérations d’une boucle et déclarent les données partagées ou privées. L’environnement choisit généralement une équipe adaptée aux ressources disponibles, sous réserve de la configuration.
OpenMP automatise la création et la répartition, pas le raisonnement sur les dépendances. Une boucle où l’itération i + 1 dépend d’une valeur produite par l’itération i ne devient pas correcte simplement parce qu’une directive la rend parallèle. Le programmeur doit encore analyser la propriété des données et l’indépendance des tâches.