19 ETUDE DU PARTITIONNEMENT ET DE L’ORDONNANCEMENT DE TÂCHES CYCLIQUES SUR UNE ARCHITECTURE DISTRIBUÉE, COMPOSÉE D’UN TERMINAL MOBILE 3G ET D’UN SERVEUR DE CALCUL Arthur Noseda Sous la direction de Laurent Freund (École Supérieure d’Ingénieurs de Marseille) Résumé 1. Ce mémoire de DEA présente une architecture hétérogène distribuée, constituée d’un terminal mobile de troisième génération (3G) et d’une machine distante, disponible pour effectuer des tâches que le terminal seul, ne pourrait pas ordonnancer. Un algorithme génétique, hérité de la théorie du développement des espèces, est utilisé pour réaliser le partitionnement de tâches cycliques que l’on souhaite exécuter. L’ordonnancement proposé est une adaption du classique algorithme à priorités dynamiques EDF (Earliest Deadline First) de Liu et Layland. INTRODUCTION Les récentes avancées en matière de téléphonie mobile, notamment avec l’avènement de la troisième génération de protocoles, dont l’UMTS (Universal Mobile Telecommunications Service), apportent de nouvelles perspectives pour la conception de systèmes informatiques toujours plus performants. Ainsi, les débits théoriques annoncés dans les spécifications de l’UMTS, disponibles sur [16], encouragent le développement d’applications distribuées utilisant ce moyen pour interconnecter les machines distantes. On peut modéliser certaines de ces applications complexes, parallèles, comme des tâches cycliques temps réel, dont la principale caractéristique est de répéter un traitement à intervalles réguliers sans autoriser de dépassement par rapport aux délais prévus. Un programme de compression de flux représente un bon exemple de cette classe d’applications. La possibilité d’utiliser un réseau rapide permet au terminal de l’utilisateur de déporter les exécutions que son processeur embarqué n’est pas en mesure d’exécuter par manque de puissance. On demande alors la migration d’une partie de l’application vers une machine dédiée au calcul. Une telle architecture pose inévitablement des problèmes de partitionnement et d’ordonnancement pour les tâches proposées au système, c’est ce que nous allons essayer de voir dans le présent mémoire. Nous évoquerons dans une première partie quelques points importants concernant les algorithmes de partitionnement et d’ordonnancement. Nous présenterons ensuite dans les détails l’architecture que nous étudions. La partie suivante sera consacrée à la solution retenue pour partitionner et ordonnancer les tâches. Enfin nous parlerons brièvement des travaux à venir. 2. ALGORITHMES DE PARTITIONNEMENT ET D’ORDONNANCEMENT Le partitionnement et l’ordonnancement de tâches sont deux problèmes récurrents dans le domaine des systèmes temps réel. Le partitionnement consiste à attribuer à chacune des sous-tâches d’un programme un processeur sur lequel se fera l’exécution. On désigne par ordonnancement, le fait d’allouer des res291 292 ARTHUR NOSEDA sources et du temps aux sous-tâches sur un processeur donné, de telle manière que certaines conditions soient remplies. Classiquement, dans les systèmes distribués, chaque processeur dispose de son propre ordonnanceur, et un protocole de synchronisation est mis en place, pour assurer la cohérence du système dans son ensemble. 2.1 PARTITIONNEMENT Il existe beaucoup d’algorithmes de partitionnement pour les systèmes multiprocesseurs et les systèmes distribués [2] [3]. Dans la littérature, on trouve globalement quatre grandes classes d’algorithmes : – algorithmes de liste, – algorithmes de regroupement, – algorithmes de recuit simulé, – algorithmes génétiques. algorithmes de liste. Chaque fois qu’il est sollicité, un algorithme de liste effectue deux actions : il choisit la prochaine sous-tâche à ordonnancer et le processeur sur lequel celle-ci va être exécutée. L’algorithme présenté dans [4] est une variante de l’algorithme de liste HLFET [6], dans lequel les priorités données aux tâches sont dynamiques dans le sens où, contrairement à HLFET, les priorités varient en fonction de l’état du système. Algorithmes de regroupement. Ce type d’algorithme est souvent utilisé pour minimiser l’utilisation des liens de communications. L’algorithme procède en deux temps. Tout d’abord, une phase dite de clustering regroupe les sous-tâches que l’on souhaite partitionner en modules ; pour cela, l’algorithme identifie les tâches qui communiquent le plus entre elles et les regroupent en clusters [8]. Ensuite, chaque cluster est associé à un processeur. Algorithmes de recuit simulé. Le recuit simulé est une méthode d’optimisation qui part d’une solution du problème et qui tente de l’améliorer en explorant l’espace de recherche par voisinages. L’algorithme considère les solutions du problème comme des états d’énergie du système et le but est de minimiser cette énergie. A chaque itération, on fait diminuer la ”température” qui représente le paramètre clé de l’algorithme. L’évaluation de la nouvelle solution obtenue est sujette à une probabilité d’acceptation, de manière à éviter de rester piégé dans un minimum local. Algorithmes génétiques. Ce sont des algorithmes d’optimisation, au même titre que les algorithmes de recuit simulé. Leur fonctionnement sera commenté en détail un peu plus loin, puisque la solution que nous avons retenue est basée sur l’un de ces algorithmes. 2.2 ORDONNANCEMENT Il existe dans la littérature un grand nombre d’algorithmes d’ordonnancement différents. Parmi les ordonnanceurs de tâches, on trouve deux grandes catégories : les algorithmes basés sur une horloge et les algorithmes à priorités. Quel que soit le type choisi, l’ordonnanceur d’un système temps réel doit toujours, en premier lieu, s’assurer que tous les travaux se terminent sans dépasser leur échéance (il s’agit du délai qui est imparti à chaque travail pour compléter son exécution). Il est également possible de fixer ensuite, une politique à l’ordonnanceur (minimiser le temps global d’exécution, le retard, les delais [10]...). Algorithmes à horloge. Comme leur nom peut le laisser suggérer, les ordonnanceurs appartenant à cette catégorie prennent la décision de faire s’exécuter une tâche à des instants précis, connus avant même que le système ne débute son fonctionnement. Dans la majorité des cas, les dates auxquelles l’ordonnanceur décide du comportement du système sont fixés par un chronomètre hardware. Algorithmes basés sur la notion de priorité. Un ordonnanceur basé sur ce type d’algorithmes attribue des priorités aux tâches selon une politique qui varie d’un algorithme à l’autre. Les priorités peuvent être statiques ou dynamiques et la préemption des tâches peut ou non, être supportée. Etude du partitionnement et de l’ordonnancement de tâches cycliques sur une architecture distribuée, composée d’un termina Par exemple, l’algorithme d’ordonnancement présenté dans [1] octroie des priorités d’autant plus fortes aux sous-tâches du programme à ordonnancer que leur délivrance est proche, tout en tenant compte des contraintes de précédence par la création d’un graphe des communications. Plusieurs événements peuvent amener l’ordonnanceur à prendre des décisions : – un nouveau travail est disponible, – un processeur est à l’état passif. Parmi les ordonnanceurs basés sur des priorités statiques, on peut citer RMS (Rate Monotonic Scheduling) qui ordonnance les tâches cycliques, en attribuant une priorité d’autant plus forte à une tâche que sa période est courte. Ainsi, plus la fréquence d’apparition d’une tâche est élevée, plus elle a de facilités à s’exécuter. L’ordonnanceur à priorités dynamique le plus connu est sans doute EDF (Earliest Deadline First), nous lui consacrons le paragraphe suivant. Earliest Deadline First. L’algorithme EDF, mis au point par Liu et Layland est un algorithme monoprocesseur à priorités dynamiques qui ordonnance un ensemble de tâches préemptables temps réel. Le principe de EDF est le suivant : à tout instant, la tâche dont l’échéance absolue est la plus proche, est celle qui s’exécute sur le processeur. EDF est un algorithme optimal, c’est-à-dire que s’il existe un algorithme capable d’ordonnancer un ensemble de travaux, alors EDF l’est aussi. Une formule simple, permet de vérifier l’ordonnançabilité d’un ensemble de tâches cycliques. Avec les notations exposées au paragraphe 3 : n X ei i=1 pi ≤1 Tâche Délivrance initiale Temps d’exécution Période Echéance T1 0 35 150 150 T2 0 20 100 100 T3 0 60 180 180 Figure 19.1 On représente l’ordonnancement monoprocesseur des trois tâches P cycliques T1 , T2 et T3 définies ci-dessus, par ei un diagramme de Gantt. L’ensemble formé par ces tâches est ordonnançable, car n i=1 pi = 23/30 ≤ 1. Dans l’exemple ci-dessus, toutes les tâches sont délivrées au même instant. L’ordonnanceur décide que c’est la tâche T2 qui doit commencer à s’éxécuter car c’est elle qui a l’échéance la plus proche. Lorsque l’exécution de T2 est terminée, l’ordonnanceur reprend la main et choisit la tâche T 1 . T3 est alors ordonnancée jusqu’à la date t = 100 qui correspond à la délivrance d’un nouveau travail dans T 2 . Cependant, l’échéance de ce travail étant à t = 200, T 3 conserve la main et complète son exécution à t = 115... 294 3. 3.1 ARTHUR NOSEDA MODÉLISATION ARCHITECTURE ÉTUDIÉE Il s’agit d’une architecture hétérogène distribuée, composée de deux machines distinctes. L’utilisateur dispose d’un terminal mobile (téléphone portable, PDA...) de troisième génération (3G), capable d’établir une connexion rapide vers une autre machine disponible pour effectuer des calculs. Les récentes normes de téléphonie mobile permettent d’envisager ce type d’architecture grâce aux importants débits proposés et à la qualité de service (QoS) garantie par les opérateurs et les équipementiers. C’est sur cette architecture particulière que l’on cherche à exécuter les tâches cycliques, dont le modèle incrémental est décrit ci-après. 3.2 MODÈLE DU GRAPHE DE TÂCHES De façon générale, une tâche est une activité qui consomme des ressources (mémoire, temps CPU) de la machine sur laquelle elle s’exécute. Si l’on reprend l’architecture exposée ci-dessus, il est clair qu’une même tâche Ti , ordonnancée sur le terminal mobile ou sur la machine distante ne se comportera pas de la même manière. En particulier, le temps d’exécution de la tâche (c’est-à-dire, le temps CPU dont la tâche Ti a besoin, si elle est seule à s’exécuter, pour terminer son exécution) sera différent. On note e i,l le temps d’exécution de la tâche T i sur le terminal et ei,r le temps d’exécution de cette même tâche sur la machine distante. De façon générale, lorsqu’on souhaite discuter du temps d’exécution de T i , sans préciser sur quelle machine cette tâche est ordonnancée, on écrit simplement e i . On peut modéliser un programme informatique comme un graphe acyclique orienté G = {T, C}, où T = {Ti ; i ∈ IN} est l’ensemble des tâches qui composent le programme et C est l’ensemble des arcs orientés {Ci,j } qui représente à la fois les contraintes de précédence et les flux de données. Chaque arc Ci,j comporte un label ci,j qui indique le volume de données que T i envoie à Tj à chaque invocation. Le volume de données ci,j n’est à considérer que dans le cas où T i et Tj sont exécutés sur deux machines différentes. Dans le cas contraire, puisque les deux tâches utilisent les mêmes segments de mémoire, on fait l’approximation que le coût de communication est nul. Figure 19.2 3.3 Exemple de graphe de tâches MODÈLE DE TÂCHE TEMPS RÉEL L’exécution d’une tâche dans un système temps réel rigide doit respecter des contraintes de temps strictes. En particulier, il est primordial que l’exécution de la tâche se termine avant que l’échéance n’arrive à son terme. On note Di l’échéance de la tâche Ti . On appelle délivrance de la tâche T i l’instant à partir duquel l’exécution de la tâche est permise. C’est en quelque sorte la date d’activation de la tâche. On note r i la délivrance de la tâche Ti . Etude du partitionnement et de l’ordonnancement de tâches cycliques sur une architecture distribuée, composée d’un termina Figure 19.3 3.4 La tâche Ti démarre peu après son activation et se termine avant l’échéance MODÈLE DE TÂCHE PÉRIODIQUE Dans les systèmes temps réel rigide, il est fréquent que l’on veuille qu’un travail s’exécute à intervalle régulier, de manière périodique. C’est le cas des systèmes de contrôle, qui vérifient à chaque exécution que tel sous-système se comporte de la manière prévue. Le modèle de tâche périodique, présenté dans [9] est adapté à la description de ce type de tâches. De manière formelle, une tâche périodique T i est la séquence de ses n travaux. On note J i,k le kième travail de Ti . Figure 19.4 La tâche périodique Ti est constitué d’une séquence de travaux Ji,k (pour tout k ∈ [1 . . . n]). Les flèches reliant les travaux de la deuxième ligne indiquent le transfert de données d’un travail vers son successeur Reprenons l’exemple du système de contrôle. Certainement, chaque travail dans la tâche est un travail complexe, que l’on peut avoir intérêt à représenter sous la forme d’un graphe, à la manière du modèle énoncé plus haut. A ce stade, il convient de faire une remarque sur les notations employées car il peut y avoir une confusion sur les termes. Dans le modèle de tâche périodique, on appelle tâche, à la fois la séquence des travaux et le modèle d’exécution, c’est-à-dire le motif qui va être répété par chacun des travaux. Dans le modèle du graphe de tâches, on appelle tâches, les nœuds d’exécution du graphe. Cette dernière définition n’a d’ailleurs que peu de rapport avec les deux précédentes. Le mot tâche est employé trois fois, pour désigner trois choses différentes. Afin de clarifier un peu la situation, nous parlerons désormais de sous-tâches pour désigner les nœuds d’un graphe de tâches, et nous réserverons le terme de tâche aux deux autres sens. Ti représente la tâche périodique, c’est-à-dire la séquence de ses travaux. Le motif de T i est un graphe de sous-tâches. On lui associe une période p i , une échéance Di et une phase φi qui dénote de façon pratique la délivrance du premier travail (J i,1 ). Figure 19.5 La tâche périodique Ti est constituée d’une séquence de travaux Ji,k . Le motif de la tâche périodique est représenté dans le premier travail, sous forme d’un graphe 3.5 MIGRATION DE TÂCHES Dans l’architecture que nous venons de présenter, nous supposons que le terminal mobile de l’utilisateur constitue l’interface par laquelle un nouveau graphe de tâches périodique est ajouté au système. 296 ARTHUR NOSEDA Ainsi, les sous-tâches à exécuter, qu’elles soient ordonnancées sur le terminal ou sur la station distante, arrivent en premier lieu sur le terminal, pour y être évaluées. Notez bien que dans la suite de ce mémoire, lorsqu’on parle de migration, on ne s’intéresse jamais à cette première migration, obligatoire, compte tenu du caractère dynamique du système. Si l’ordonnanceur décide que la sous-tâche T i doit être exécutée sur la machine distante, il est nécessaire de faire migrer la partie exécutable correspondante vers celle-ci. De nombreuses recherches menées dans le domaine ont apporté des résultats très enthousiasmants. Ainsi, une unité de recherche de l’INRIA, vient de publier un résultat fondamental sur la migration des processus légers Java. Il est désormais possible de transférer un thread Java d’une machine à une autre, en conservant l’état dans lequel se trouvait le thread, ceci sans surcharge pour le réseau. Dans notre architecture, la migration est prise en compte par un temps de migration m i pour chaque sous-tâche Ti . 4. RÉSULTATS En général, le problème du partitionnement et de l’ordonnancement de tâches cycliques est NPdifficile au sens fort [9]. L’approche la plus fréquemment mise en œuvre est donc de trouver une solution sous-optimale à l’aide d’une heuristique. La solution retenue est basée sur la minimisation d’une expression combinatoire exprimant tous les liens de communications possibles, à l’aide d’un algorithme génétique. 4.1 FORMULATION DU PROBLÈME Le problème est donc, dans un premier temps, de partitionner un ensemble de tâches périodiques, c’est-à-dire de choisir un processeur cible pour chaque sous-tâche. Pour effectuer convenablement ce choix, nous fabriquons une fonction de coût caractérisant le coût de communications total de notre système : on prend en compte toutes les communications entre n’importe quelle paire de sous-tâches Ti et Tj , et on se propose de minimiser l’expression. Pour résoudre le problème, nous allons procéder en deux temps. Trouver une solution acceptable à notre partitionnement, au sens qu’elle minimise suffisament la fonction de coût, puis vérifier que le partitionnement proposé est ordonnançable. Pour que nos calculs aient un sens, nous devons ramener les coûts de communications sur une durée commune pour tous les graphes Gi : l’hyperpériode. Il s’agit du plus petit commun multiple des p i . On note H l’hyperpériode du système. Par suite, on note C i,j le coût des communications de Ti vers Tj durant une hyperpériode. Si Ti et Tj sont placés sur le même processeur, alors C i,j est considéré nul. On introduit le coefficient Ai représentant l’allocation de la sous-tâche T i . Ai est défini de la manière suivante : si Ti est placé sur le terminal de l’utilisateur, A i = 1, sinon Ai = 0. La fonction de coût que nous cherchons à minimiser : Ctotal = n n X X i=1 j=1 (1 − δi,j )Ai (1 − Aj )Ci,j avec δi,j = 1 si i = j, 0 sinon. 4.2 ALGORITHME GÉNÉTIQUE Les algorithmes génétiques reposent sur les principes fondamentaux de la génétique. De façon générale, un algorithme génétique est un algorithme itératif de recherche globale dont le but est d’optimiser une certaine fonction. Dans le problème du partitionnement des sous-tâches en deux modules, nous nous servons de cet algorithme pour minimiser la fonction de coût chiffrant toutes les communications du système. Pour atteindre cet objectif, l’algorithme travaille en parallèle sur une population d’objets informatiques appelés chromosomes, distribués dans tout l’espace de recherche. Les gènes des chromosomes de notre problèmes sont les Ai (pour tout i ∈ [1 . . . n]). A chaque itération, appelée génération, l’algorithme crée une nouvelle population de chromosomes. On s’arrange, par divers mécanismes pour que les chromosomes de la nouvelle génération soient mieux adaptés que ceux de la précédente, c’est-à-dire que le Etude du partitionnement et de l’ordonnancement de tâches cycliques sur une architecture distribuée, composée d’un termina patrimoine génétique des chromosomes amène la fonction de coût (également appelée fonction fitness) à tendre vers son optimum. L’algorithme génétique se déroule de la manière suivante : 1. génération de la première population 2. évaluation (critère d’arrêt) 3. sélection pour la reproduction 4. croisement et mutation 5. recyclage générationnel, retour en 2. Génération de la première population. Cette population est générée de manière aléatoire. Concrètement, chaque chromosome dispose d’autant de gènes qu’il existe de sous-tâches candidates au placement. Les gènes sont initialisés aléatoirement à 0 ou 1. Evaluation. On évalue la fonction de coût pour chaque chromosome de la population courante. Pour cela, chaque chromosome calcule la fonction de coût avec les valeurs contenues dans ses propres gènes. On vérifie ensuite que la solution proposée ne surexploite pas l’une ou l’autre des deux machines de notre architecture. Pour cela, on fait la somme des facteurs d’utilisation des sous-tâches groupées dans chaque module. Si pour l’un ou l’autre processeur, le facteur d’utilisation dépasse 1, on refuse la solution. Si l’évaluation retourne un bon placement, on arrête la recherche d’une meilleure solution. Si aucune réponse satisfaisante n’est trouvée au terme d’un certain nombre d’itérations, on décide de rejeter la ou les tâches dernièrement soumises. Sélection. Il existe plusieurs manières pour effectuer la sélection des chromosomes. La méthode que nous avons choisie consiste simplement à ranger dans un tableau, les chromosomes par ordre de fitness (le résultat de la fontion coût s’appelle le fitness dans les algorithmes génétiques). Ainsi, les meilleures solutions sont placées en tête de liste. De plus à chaque case du tableau est associée une probabilité de sélection, d’autant plus élevé que le fitness est petit (puisque nous cherchons à minimiser la fonction de coût). Croisement et mutation. Les méthodes de croisement et de mutation permettent de créer de nouveaux individus. Les croisements s’effectuent sur les individus sélectionnés avec la sélection par rang. Avec deux chromosomes parents, nous générons deux chromosomes enfants. Pour que les gènes ne restent pas figés, on effectue, sous une certaine probabilité (le taux de mutation), une mutation chez un individu tiré au hasard parmi les individus enfants issus des croisements. Figure 19.6 Exemple de croisement : la génération suivante est créée en inversant les n derniers gènes des parents (dans cet exemple, on a pris n = 4). Nouvelle génération. La nouvelle génération est constituée des nouveaux individus créés par croisement et mutation ainsi que les meilleurs chromosomes de la population précédente. Le nombre de meilleurs chromosomes que l’on garde est déterminé par le taux de reproduction. 4.3 SOLUTION PROPOSÉE Partitionnement à base d’algorithme génétique. Pourquoi avoir choisi un algorithme génétique plutôt qu’un autre algorithme d’optimisation (recuit simulé, itératif local...). La raison principale est que l’espace de recherche, qui dépend directement des tâches cycliques que l’on exécute sur l’architecture, 298 ARTHUR NOSEDA n’a aucune ”bonne” propriété facilitant le problème. Dans ces conditions, les autres algorithmes d’optimisation aboutissent souvent à un optimum local, au contraire des algorithmes génétiques [15]. Une des contraintes de notre architecture, le fait que l’interface soit le terminal mobile, traditionnellement limité en capacité de calcul, plaide en la défaveur de l’utilisation d’un algorithme génétique, dont les temps d’exécution sont plutôt élevés (du même ordre que ceux du recuit simulé, mais bien supérieurs à ceux d’un algorithme de liste). Une solution peut être de limiter la population en conséquence, avec les risques de passer à côté d’une bonne solution. Ceci étant, à moins de faire effectuer le partitionnement par la machine distante (ce que nous souhaiterions éviter, autant que faire se peut), ce problème sera récurrent dans notre architecture. En revanche le traitement à base d’algorithme génétique présente une bonne caractéristique par rapport à l’implémentation qui en est pressentie. Outre l’actualité des protocoles 3G (UMTS, EDGE et GPRS), l’idée de départ qui a motivée ce mémoire, était l’émergence de la programmation en langage Java dans la téléphonie mobile. J2ME de Sun Microsystems (http ://java.sun.com/j2me/), fournit un environnement de développement et d’exécution d’applications Java, simplifiés par rapport au Java traditionnel. Au chapitre des modifications, on peut entre autres noter la disparition des nombres à virgule flottante, ce qui a pour effet de limiter, voire d’interdire l’implémentation d’algorithmes tel que le recuit simulé, pour lesE quels il est primordial de pouvoir calculer le terme e − kT , forcément réel. Il est par contre parfaitement envisageable de proposer une implémentation d’un algorithme génétique pour le problème d’optimisation qui nous intéresse, sans l’usage des flottants. La compléxité algorithmique dépend directement de ce que l’ordonnanceur est en mesure de savoir au moment de partitionner. La formule donnant le coût de communications total et les tests de validations demande de la part de l’ordonnanceur la connaissance : – de l’hyperpériode H, calculée en une passe, – des facteurs d’utilisation de chaque sous-tâche pour les deux processeurs, – des coûts de migration de chaque sous-tâche, – de la liste complète des communications. Si celle-ci n’est pas fournie, elle peut être obtenue en une passe sur l’ensemble des sous-tâches. Une fois ces informations acquises, le calcul de la fonction fitness de chaque chromosome se résume à une simple addition. Dans un système monoprocesseur ou multiprocesseur, pour savoir si un processeur est surchargé de sous-tâches à exécuter, c’est-à-dire si trop de sous-tâches ont été associées à ce processeur, on réalise un test simple sur la somme des facteurs d’utilisation mis en jeu. Soit m le nombre de sous-tâches associé à un processeur P . On s’assure de la non surcharge en vérifiant que : m X ei i=1 pi ≤1 Dans notre système distribué, ce test est à peine plus compliqué. Rappelons les rôles dissymétriques des deux machines : le terminal mobile de l’utilisateur reçoit par migration le code exécutable des tâches cycliques. A l’issue du partitionnement des tâches, il faut faire migrer les sous-tâches dont l’exécution est prévue sur la machine distante. La migration n’a lieu qu’une fois, en préambule de la première exécution de la sous-tâche. La migration d’une tâche est un processus qui consomme du temps CPU aux deux machines : le terminal se charge de l’émission du code, tandis que la machine distante réceptionne. Ce temps CPU consommé est intimement lié au volume du code exécutable. On définit alors les fonctions test suivantes, respectivement pour le terminal et pour la machine distante, avec n le nombre total de sous-tâches : n m X X ei mi + ≤1 pi pi i=m+1 i=1 n X i=m+1 ei + m i ≤1 pi Il reste à tenir compte des communications induites par les contraintes de précédence. Comme pour la migration, les communications peuvent être perçues comme des couples producteur-consommateur. Etude du partitionnement et de l’ordonnancement de tâches cycliques sur une architecture distribuée, composée d’un termina Dans la majorité des cas, une communication aura lieu entre deux sous-tâches de même période. Si cela n’est pas le cas, tout dépend des mécanismes de synchronisation mis en œuvre. Si les deux tâches sont synchronisées, les équations obtenues précédemment deviennent, avec b la bande passante disponible entre les deux machines : m X ei i=1 pi + n n n X ci,j mi X X + ≤1 pi min(pi , pj )b i=m+1 i=1 j=1 n n n X ci,j ei + m i X X + ≤1 pi min(pi , pj )b i=m+1 i=1 j=1 Le partitionnement obtenu à l’aide de l’algorithme génétique utilisé, doit vérifier ces deux dernières expressions, sinon le chromosome dont le fitness n’a pas vérifié ces contraintes est rejeté et un nouveau chromosome créé aléatoirement le remplace. Ordonnancement. Suivant l’approche choisie, l’ordonnancement peut être un problème bien plus délicat que le partitionnement. Globalement deux solutions sont possibles : une solution avec un seul ordonnanceur et une solution avec deux ordonnanceurs (et un protocole de synchronisation entre les deux pour maintenir le système dans un état cohérent). La première solution a l’avantage d’être beaucoup plus simple que la deuxième — même si c’est souvent cette dernière approche que l’on retrouve le plus fréquemment — et c’est donc un algorithme EDF centralisé qui a été choisi pour ordonnancer les travaux sur les deux processeurs. Centralisé implique aussi que c’est au terminal mobile que revient ce rôle. Quelle que soit la solution adoptée, un ordonnanceur sur plateforme distribuée fonctionne par envoi de messages, soit en direction d’un autre ordonnanceur, soit directement à l’OS de l’autre machine. On fait l’approximation que ces messages ne perturbent pas le système (pas de surcharge des liens de communications ni de temps CPU prélevé). Concrètement, les différences par rapport à l’algorithme EDF standard se situent au niveau des migrations et des communications. Celles-ci peuvent être considérées comme des extensions d’un travail élémentaire de Ji,k , du point de vue temps d’exécution. Plus clairement, si on considère une tâche qui doit s’exécuter sur la machine distante ; avant que le premier travail ne puisse démarrer, il faut migrer le fragment de code (le thread) correspondant. Pratiquement, on accolle le travail de migration au premier travail de la tâche, et on considère le temps d’exécution total : ei,ltotal = mi ei,rtotal = ei,r + mi De même pour les communications entre deux travaux n’appartenant pas à la même partition : on considère qu’un travail n’est réellement terminé que lorsque il a communiqué ses résultats aux travaux en attente de ceux-ci. On note nf le nombre de nœuds adjacents à une sous-tâche T i . La formule cidessous représente le temps d’exécution effectif de la sous-tâche T i : ei,ltotal = ei,l + nf X ci,j j=1 b On considère maintenant une sous-tâche T j sur la machine distante, impliquée dans la communication : ci,j ei,rtotal = b Les formules sont identiques pour une communication d’un travail de la machine distante vers des travaux du terminal mobile. A priori le problème de l’inversion de priorité soulevé dans [11] ne se pose pas. 300 5. ARTHUR NOSEDA PERSPECTIVES Il reste beaucoup d’interrogations concernant le modèle proposé, entre autres parce que la phase de simulation n’a pas encore commencé. Premièrement, le choix de l’algorithme génétique, s’il se prête particulièrement bien à la forme du problème, amène un grand nombre de traitements en plus des tâches que l’on souhaite ordonnancer. Ce nombre est d’autant plus grand que la population choisie est importante. Il faudra donc mesurer la surcharge induite par l’utilisation de cette méthode, en fonction de la population que l’on se fixe... Peut-être faudra-t-il se tourner vers une heuristique de regroupement de sous-tâches, plus difficile à prouver, mais probablement moins gourmande en mémoire et en temps CPU. Quand toutes ces questions auront été résolues, on pourra chercher à faire évoluer le modèle. Des travaux comme ceux de Gul Agha et Carlos Varela [13] sont des sources d’inspirations. Ces travaux présentent une infrastructure complète pour la programmation d’applications reconfigurables. Il serait alors possible d’utiliser Internet comme une gigantesque plateforme de calcul distribuée, à l’aide d’acteurs mobiles programmés avec SALSA [12]. Avec un tel modèle, il devrait être possible de proposer à l’utilisateur du terminal mobile une capacité de calcul bien plus importante. Références [1] Krithi R AMAMRITHAM, ”Allocation and Scheduling of Precedence-Related Periodic Tasks” IEEE Transactions on Parallel and Distributed System, Vol.6, No. 4, April 1995 [2] El-Ghazali TALBI, ”Allocation dynamique de processus dans les systèmes distribués et parallèles” Laboratoire d’Informatique Fondamentale de Lille - Université des Sciences et Technologies de Lille, Report 95-162, 1995 [3] Trian M UNTEAN, El-Ghazali TALBI, ”Méthodes de placement statique des processus sur architectures parallèles”, Technique et science informatiques, Vol. 10, No.5, 1991 [4] Gilbert C. S IH, Edward A. L EE, ”A Compile-Time Scheduling Heuristic for Interconnection-Constrained Heterogeneous Processor Architectures”, IEEE Transactions on Parallel and Distributed Systems, Vol. 4, No. 2, February 1993 [5] Binoy R AVINDRAN, Pushkin K ACHROO, Tamir H EGAZY, ”Intelligent Feedback Control-based Adaptive Resource Management for Asynchronous, Decentralized Real-Time Systems”, IEEE Transactions on Systems, Man and Cybernetics - Part C : Applications and Reviews, Vol. 31, No. 2, May 2001 [6] Benjamin S. M ACEY, Albert Y. Z OMAYA, ”A Performance Evaluation of CP List Scheduling Heuristics for Communication Intensive Task Graphs”, IPPS/SPDP 1998 [7] Renaud L EP ÈRE, Grégory M OUNI É, ”Ordonnancement de tâches malléables”, Calculateurs parallèles, août 2000 [8] Jean-Pierre B EAUVAIS, Anne-Marie D ÉPLANCHE, ”Affectation de tâches dans un système temps réel réparti”, Technique et science informatiques, Vol. 17, No. 1, 1998 [9] Jane W. S. L IU, ”Real-Time Systems”, Prentice Hall (ISBN 0-13-099651-3), 2000 [10] Tarek F. A BDELZAHER, Kang G. S HIN, ”Optimal Combined Task and Message Scheduling”, IEEE Real-Time Systems Symposium, 1995 Etude du partitionnement et de l’ordonnancement de tâches cycliques sur une architecture distribuée, composée d’un termina [11] Lui S HA, Ragunathan R AJKUMAR, John P. L EHOCZKY, ”Priority Inheritance Protocols : An Approach to Real-Time Synchronization”, IEEE Transactions on Computers, Vol. 39, No. 9, September 1990 [12] Carlos A. VARELA, Gul AGHA, ”Programming Dynamically Reconfigurable Open Systems with SALSA”, SIGPLAN Notices, Vol. 36, 2001 [13] Carlos A. VARELA, ”Worldwide Computing with Universal Actors : Linguistic Abstractions for Naming, Migration, and Coordination”, Thesis submitted in the Graduate College of the University of Illinois at Urbana-Champaign, 2001 [14] Sara B OUCHENAK, Daniel H AGIMONT, ”Zero Overhead Java Thread Migration”, Rapport technique de l’INRIA - Rhone-Alpes, juin 2002 [15] El-Ghazali TALBI, Pierre B ESSI ÈRE, Juan A HUACTZIN, Emmanuel M AZER, ”Un algorithme génétique parallèle pour l’optimisation” Technique et science informatiques, Vol. 15, No. 8, 1996 [16] http ://www.3gpp.org