• Aucun résultat trouvé

L’architecture en exo-noyau permet le développement de bibliothèques standards au-dessus des couches basses de l’exo-noyau, constituées par les modules hexo et mutek. Il s’agit ici de pro-poser des services relatifs à l’exécution parallèle et à la gestion des tâches et contextes d’exécution, services indispensables dans un contexte multiprocesseur.

Une des motivations principales du support natif de l’hétérogénéité par le système d’exploitation est de rendre accessible les plateformes hétérogènes aux applications déjà existantes, alors que les autres approches impliquent un développement spécifique. Le support de bibliothèques standards telles que PThread ou OpenMP permet à la fois d’assurer la généricité de la solution, de valider l’implémentation et d’élargir le spectre d’utilisation du noyau.

Cette section présente les principales bibliothèques de parallélisation proposées par MutekH.

4.3.1 La bibliothèque de Threads POSIX

Cette bibliothèque incontournable dans le domaine de la programmation parallèle est proposée par le module libpthread, elle est un sous-ensemble de l’API POSIX. La norme POSIX spécifiant l’ensemble de l’API d’un système de type UNIX, elle est liée à la notion de processus et aux concepts propres à UNIX d’une manière générale. Ceci soulève des problèmes similaires à ceux que l’on a déjà mentionnés à propos de la bibliothèque C standard, quand on souhaite une implémentation sortant du cadre d’UNIX.

L’extension Threads extensions de la norme POSIX reste suffisamment indépendante des concepts d’UNIX pour permettre l’implémentation d’un large sous-ensemble de services indépendants d’UNIX. Dans cette bibliothèque, le contexte d’exécution est un thread et sa spécification reste abstraite de la notion de processus UNIX. Seules quelques fonctions relatives à la gestion des signaux et à la mémoire partagée des processus UNIX doivent être laissées de côté. Cette approche est retenue par de nombreux noyaux pour systèmes embarqués proposant également cette bibliothèque.

4.3. LES SERVICES STANDARDS DE PARALLÉLISATION 81 Les primitives de synchronisation

Deux types de services sont proposés par cette bibliothèque : la possibilité de créer des nouveaux contextes d’exécution et la possibilité de synchroniser leur exécution au travers de diverses primi-tives. La figure 4.9 montre comment les couches basses du noyau MutekH permettent d’implémenter la primitive de synchronisation mutex de POSIX.

Des versions étendues de l’API proposent des primitives de synchronisation supplémentaires : la primitive rwlock à exclusion mutuelle avec distinction entre les lecteurs et écrivains, ou encore la primitive spinlock de verrous à attente active.

Le système de configuration de MutekH permet de choisir de manière fine quelles primitives de synchronisation doivent être supportées par le noyau.

La placement des tâches

Le placement des threads sur un processeur particulier, lors de leur création, n’est pas pris en charge par l’API standard de la bibliothèque POSIX, cependant des extensions permettent de forcer l’assi-gnation d’un thread sur un processeur. Cette fonctionnalité est importante dans le cadre d’un système hétérogène où l’exécution d’une tâche particulière peut être adaptée à un type de processeur. L’ordonnanceur de MutekH définit des files d’exécution pour un processeur ou pour un groupe de processeurs, selon la politique de migration de contextes choisie dans la configuration. La biblio-thèque libpthread propose un attribut non standard utilisable avec la fonction pthread_create. Cet attribut permet à la bibliothèque de choisir les files d’exécution adaptées. La figure 4.10 donne un exemple de code associant un thread à un processeur.

Dans le cadre d’un système hétérogène, lorsque l’ordonnanceur est configuré pour disposer d’une file d’exécution par processeur, cet attribut force l’exécution du thread sur le processeur spécifié. Quand aucun attribut n’est utilisé le thread s’exécute sur le processeur qui exécute la fonction de création.

Lorsque l’ordonnanceur est configuré pour partager une file d’exécution entre plusieurs processeurs, il existe au moins une file d’exécution par type de processeur et le thread n’est élu que par les processeurs désignés par l’attribut. Si aucun attribut n’est utilisé, le thread est libre de s’exécuter sur n’importe quel processeur du même type lors de chaque élection.

pthread_t th; pthread_attr_t at; pthread_attr_init(&at);

/* assign thread to cpu 0 */

pthread_attr_affinity(&at, 0);

pthread_create(&th, &at, th_func, NULL); pthread_attr_destroy(&at);

82 CHAPITRE 4. RÉALISATION DU NOYAU

4.3.2 La bibliothèque OpenMP

Le standard OpenMP propose une extension du langage de programmation C (mais aussi C++ et For-tran), permettant d’exécuter certaines sections de code en parallèle dans différents contextes d’exé-cution.

La création de threads n’est pas explicite dans le code de l’application qui se contente d’exprimer quelles parties du programme peuvent être exécutées en parallèle via des directives de compilation dédiées. La figure 4.11 donne un exemple simple d’utilisation d’OpenMP.

size_t i; char data[100];

#pragma omp parallel for for (i = 0; i < 100; i++)

data[i] *= 2;

FIGURE4.11 – Exemple de code C utilisant une directive OpenMP de parallélisation de boucle

L’implémentation d’OpenMP nécessite la collaboration du compilateur et d’une bibliothèque asso-ciée. Cette bibliothèque prend en charge la création de contextes d’exécution et leur synchronisation. Les fonctions de création d’un contexte d’exécution doivent respecter les attentes du code généré par le compilateur pour réaliser ces actions, bien que les appels à ces fonctions ne soient pas explicites dans le code source.

Le module libgomp de MutekH est un portage de la bibliothèque OpenMP associée au compilateur C GNU. Cette bibliothèque a été conçue de manière portable et dispose de plusieurs modules pour supporter les environnements d’exécution parallèles de différents systèmes d’exploitation. L’ajout du support pour MutekH en a été facilité.

Le standard OpenMP ne prévoit pas de spécifier quels processeurs doivent être utilisés pour l’exécu-tion parallèle d’un bloc de code donné. Cependant plusieurs politiques existent quant à l’allocal’exécu-tion et la création des contextes d’exécution qui seront utilisés par la suite pour traiter le parallélisme. L’utilisation d’OpenMP standard dans le cadre des systèmes hétérogènes permet donc de paralléliser l’application, mais elle ne permet pas de choisir dynamiquement le type de processeur à utiliser pour un bloc de code donné. Ceci est une limitation empêchant qu’une application basée sur OpenMP tire parti de l’hétérogénéité de la plateforme, mais n’exclut pas sa cohabitation avec d’autres biblio-thèques de parallélisation.

OpenMPpropose une directive permettant l’exécution d’un bloc de code donné, sur le processeur maître uniquement. Dans la même optique de sélection des processeurs, il serait tout à fait envi-sageable d’étendre OpenMP pour sélectionner le type de processeur devant traiter un bloc de code dans une plateforme hétérogène. Cette approche sort du cadre de cette thèse car elle nécessite la modification du compilateur et ne traite pas le problème des applications existantes.

4.4. LES AUTRES SERVICES 83