• Aucun résultat trouvé

Deuxième approche : prise en compte du contexte : notre apport

5.4 Algorithme génétique

5.4.3 Deuxième approche : prise en compte du contexte : notre apport

5.5 Conclusion . . . . 81

5.1 Présentation générale

Dans ce chapitre, nous développons la modélisation du problème de mesure du pire temps

d’exécution d’une fonction dans un système complexe, sans accès au code source. Nous définissons,

par la suite, notre approche et détaillons la solution dynamique retenue. Nous concluons sur l’intérêt

de notre apport et préparons les résultats expérimentaux qui seront présentés au chapitre suivant.

5.2 Modélisation

Nous commençons par modéliser mathématiquement notre problématique, afin de définir quelle

heuristique peut répondre au problème fixé. Nous déterminons dans un premier temps, la fonction

objectif. Cette fonction résume le problème à étudier. Dans notre cas, la fonction objectif est

contexte d’exécution du système. Par paramètre, nous entendons paramètre de la fonction testée,

et par contexte, l’état du système. Le contexte sera plus détaillé dans la section suivante.

Les variables de décision, permettant de définir celles qui ont une influence sur notre choix sont

donc :

— le ou les paramètres de la fonction à tester ;

— le contexte d’exécution du système.

Suite à cette base, nous y incluons un certain nombre de contraintes :

— Il existe un nombre fixende fonctionsfipossibles sur le système aveci < n. Chacune de ces

fonctionsfi peut prendre un ensemble de paramètres qui influencent, eux aussi, l’évolution

du système ;

— Chaque élément de base (que nous appellerons gène par la suite) représente une des n

fonctions ;

— Il doit y avoir une successions deKélément de basesfiainsi que leurs paramètres associés,

appelésC, (que nous appellerons chromosome par la suite) permettant de résoudre au mieux

le problème ;

— Il existe un nombre maximal de fonctions exécutables consécutivement< K (liée aux limites

des systèmes réels et aux technologies utilisées) ;

— Pour chaque fonction il existe un nombrej de paramètres p avec, pour chacun d’eux, un

intervalle de valeurs compris dansN (naturel) ;

— Il existe des contraintes de variables liées entre elles. Une variable liée est une variable

utilisant un ou des paramètres pconçus ou modifiés par l’exécution préalable d’une autre

fonction et générant une dépendance obligatoire entre elles (les variables liées sont de type

fonctionnelles ou de données, telle que les fonctions d’initialisations ou les fonctions de

création/destruction de tâches, en considérant qu’une tâche ne peut être détruite si elle

n’existe pas). Ce problème relève plus d’une difficulté d’implémentation que d’un problème

algorithmique ;

— L’évaluation de la séquence des fonctions (gènes) qui compose un chromosome donné est

toujours envisagée sur un système dans l’état initial (déterministe), qui est l’état initial

étant l’état obtenu par le système à la fin de son démarrage normal (boot) et en attente de

la première fonction à exécuter ;

— Il existeX résultats composés de C successions d’éléments de bases, répondant au mieux

au problème.

L’ensemble de ces contraintes sont la modélisation mathématique du problème cité au dessus.

Ainsi le non-accès au code source est représenté par le fait qu’il n’est possible d’appeler que des

fonctions du système avec leurs paramètres respectifs. Celles-ci sont bornées et non-nulles. Pour

simplifier le discours nous considérons que la dernière fonction à tester est celle que nous souhaitons

évaluer. Ce n’est pas un paramètre de notre algorithme mais une simplification du discours, amenant

à une meilleure lisibilité.

Nous pouvons observer dans la définition des contraintes que nous prenons en compte l’existence

d’un système réel avec des bornes maximales de fonctionnement liées aux technologies utilisées et

à leurs limites physiques. Nous avons également pris en compte la nécessité de pouvoir rejouer

C’est le cas de l’avant dernière contrainte qui nous permet d’avoir toujours un état initial neutre

au début de chaque test.

L’ensemble de la modélisation nous prouve que le problème est bien un problème d’optimisation,

plus précisément, un problème méta-heuristique. La dernière contrainte nous permet de conclure sur

l’intérêt qu’un algorithme du type algorithme génétique, offrant une population de résultat, répond

au problème d’optimisation. En effet, l’espace de recherche est très vaste et particulièrement lié au

nombren de fonctions du système étudié. Il est borné par les limites technologiques du système

testé et par l’ensemble des paramètres pde chaque fonction testée. Nous pouvons donc définir la

forme de l’algorithme avec l’ensemble de ces contraintes.

Cela implique, tout de même, une vision nouvelle du contexte d’exécution d’un système.

5.3 Contexte : une nouvelle vue du fonctionnement d’un

système

Nous définissons un état logiciel et physique d’un système à un instant t comme un contexte

d’exécution (ou contexte). Voici la composition de celui-ci :

L’état physique : états de la mémoire, des périphériques, de la MMU, des caches, bus de

don-nées... ;

L’état logiciel : états internes de l’hyperviseur, et des partitions.

Le contexte est obtenu par l’exécution de fonctions successives amenant à un état précis, tel que

représenté en figure 5.1. Dans la suite de notre thèse, les fonctions successives seront les fonctions de

bases du processeur, c’est-à-dire les primitives systèmes. Celles-ci sont les plus simples et basiques

du système. Néanmoins, le contexte peut être généré par n’importe quel type de fonction, donc pas

seulement et spécifiquement les primitives.

Succession d'opérations amenant

à un état du système

Paramètres de la fonction

testée

Succession d'opérations amenant

à un état du système

Paramètres de la fonction

testée

Toto(1) puis Toto(14) puis Tata(24) puis... foo(50)

Exemple :

Avec la fonction testée foo(integer ), avec d'autres fonctions systèmes telles que toto et tata

Le nombre de paramètres inclus dans un contexte (aussi bien matériel que logiciel) est

poten-tiellement très important. Les paramètres correspondent aux paramètres des fonctions

successive-ment exécutées. Leur énumération exhaustive est difficile, car dépendante des fonctions et de leurs

nombres. L’influence du choix de ces paramètres est pourtant significative sur le temps d’exécution

de la fonction testée. Dans un cas concret d’application, le temps d’exécution d’une fonction est

influencé et dépend de l’état matériel et logiciel au moment de son exécution.

Dans le cas des hyperviseurs traités ici, le contexte d’exécution serait une succession de fonctions

hyperviseurs et/ou processeurs. Celles-ci amèneraient à un état interne de l’hyperviseur. Pour des

raisons de reproductibilité et de vitesse de calcul, les systèmes sont limités aux appels processeurs

de bases, car une fonction hyperviseur est un ensemble d’appel à des fonctions de bases.

Les questions sont : Comment intégrer cette nouvelle vision du contexte dans un algorithme

méta-heuristique ? et plus particulièrement, peut-on utiliser un algorithme génétique ? Nous

tente-rons de répondre à cette question dans la section suivante après avoir développé la particularité

d’un algorithme génétique de manière générale.

5.4 Algorithme génétique

Nous avons choisi l’algorithme génétique [Dip] pour être en mesure d’intégrer le contexte

d’exé-cution. En effet, celui-ci est déjà prédominant dans le domaine de la recherche automatique de

tests [WSJE97] mais aussi dans le domaine de la recherche du WCET [Gro03]. L’algorithme

géné-tique exploite une population de solutions partielles, et cherche à optimiser de grands espaces de

recherches. Il est donc adapté à notre problématique.

L’algorithme génétique à été proposé par Goldberg [Gol89]. Cet algorithme évolutionnaire se

base sur le principe de sélection des espèces définit par Darwin. Cette théorie de l’évolution étant

principalement d’ordre biologique, nous y retrouvons des termes associés, ainsi l’ensemble des

solutions qui peuvent résoudre le problème s’appelle population.

Les algorithmes génétiques sont fortement utilisés dans l’analyse dynamique de systèmes

infor-matiques [Bou06,G´05, RHP99]. Une bonne définition de ceux-ci est donnée dans [WEE+]. Ainsi

il est utilisé dans l’ordonnancement de systèmes robustes et permet de trouver le meilleur plan

d’ordonnancement possible sur ces systèmes critiques. Il est aussi utilisé en économie pour essayer

d’optimiser la courbe de la bourse par exemple [Val01].

Plus près de nos problématiques, celui-ci est également utilisé dans l’aéronautique [DG] à des

fins de gestion du trafique aérien.

L’algorithme génétique a donc aussi été étudié dans le domaine du WCET [Gol89]. Celui-ci est

encore amélioré de nos jours [Mar12].

Un algorithme génétique agit donc sur une population de chromosomes comme suit :

1. chaque chromosome représente un état possible du système ;

2. durant l’exécution, les chromosomes sont sélectionnés à l’aide d’unfitness, puis recombinés

afin de créer de nouveaux chromosomes par croisement et/ou par mutation ;

3. une grande valeur defitness offre plus de chance à un chromosome d’être sélectionné, puis

4. le processus recommence jusqu’à satisfaction d’un critère d’arrêt.

Le principe de fonctionnement général d’un algorithme génétique est visible à la figure 5.2.

Fig. 5.2 – Principe de fonctionnement de l’algorithme génétique

L’algorithme génétique utilise des chromosomes contenus dans une population et la fait évoluer

afin d’approcher au mieux le problème d’optimisation mathématique. Pour cela il existe plusieurs

phases représentées en figure 5.2 et détaillées ici :

— Génération d’une population initiale : créé des chromosomes pouvant répondre au problème

d’optimisation ;

— évaluation : détermine la pertinence de chaque chromosome pour répondre au problème

mathématique ;

— Sélection : élimine les chromosomes les moins pertinents. Chaque chromosome est exécuté

sur système réel. Le problème à optimiser (le WCET) est recherché, pour cela nous exécutons

chaque chromosome et mesurons le temps d’exécution de la dernière primitive système. Un

fitness, représentant l’intérêt du chromosome à répondre au problème d’optimisation, est

fixé (pour nous il représente la valeur du temps d’exécution mesuré en réel) ;

— Croisement et mutation : associe les chromosomes entres eux. Les chromosomes sont

sé-lectionnés préalablement par un tournoi en prenant deux paires d’individus choisis

aléatoi-rement dans la population. L’individu ayant le meilleurfitness dans chaque paire survit.

Les survivants sont sélectionnés pour générer de nouveaux chromosomes se rapprochant du

problème à optimiser (croisement des deux chromosomes sélectionnés, avec une probabilité

pcroisement que cela se réalise, en créant deux fils ) et créé une déviance (mutation en

mo-difiant potentiellement chaque gène en prenant aléatoirement dans chaque chromosome un

nouveau gène avec la probabilité que l’opération arrive, définie parpmutation) ;

— Critère d’arrêt : fixe la règle spécifiant quand l’algorithme doit arrêter la recherche du

chro-mosome optimal. L’algorithme s’arrête s’il n’y a pas d’évolution du fitness maximal de la

population depuis un certain nombre d’itération. Si la première condition n’est pas vérifiée,

l’algorithme s’arrête au bout d’un temps fixé par l’utilisateur.

Cet algorithme est déjà connu et il en existe de nombreuses variantes. Celui-ci a pourtant

été minimisé avec l’arrivée de l’analyse statique dans le domaine de la recherche. Néanmoins, de

manière générale, la recherche génétique et biologique avance et nous avons de nouvelles visions de

celle-ci [ANLBHM00]. Ces solutions doivent êtres apportées à la recherche du WCET et peuvent

nous permettre d’avancer vers des algorithmes génétiques plus pertinents et efficaces au sein d’un

système complexe tel que le nôtre.

Afin de mieux comprendre ce qui peut être évolué et amélioré dans cette algorithme génétique,

et où se trouve le verrou scientifique, nous allons observer l’approche actuelle des industriels dans

le domaine. Nous verrons ensuite nos évolutions tendant à répondre à notre problématique.

5.4.1 Première approche : techniques industrielles existantes pour le

contrôle des caractéristiques du satellite

Les industriels effectuent des tests d’évaluations du WCET en utilisant desbenchmarks. Ceux-ci,

propriétaires, ont été développés spécifiquement par certains experts pour tendre vers des

exécu-tions "normales" ou "classiques" d’un satellite. Ainsi, lesbenchmarksde typeMälardalen [GBEL10]

qui évaluent le WCET ne permettent pas d’observer une velléité d’acte malveillant ou un bogue

particulier. Celui-ci se limite à offrir un temps d’exécution théorique à effectuer une tâche, sans

garantie que cette valeur soit un pire temps d’exécution.

Les benchmarks de Mälardalen sont souvent utilisés mais principalement pour des systèmes

simples et bare-métals. Lesbenchmarks sur systèmes complexes tels que les nôtres demanderaient

un investissement certain, sans pour autant arriver à des conclusions sûres concernant la valeur du

WCET d’un système. En revanche, pour des raisons de performances, ils sont très utiles.

Afin de voir l’impact d’un système complexe et de comprendre que les testent réalisés via

bench-marksne sont pas optimaux dans notre cas d’étude, nous avons choisi de les évaluer sur un système

embarqué intermédiaire. Celui-ci est un MBDED13LPC1768 contenant un ARM Cortex-M3. C’est

la plate-forme d’exécution matérielle. Pour sa part, la cible logicielle pour l’évaluation de notre

pro-position est construite sur FreeRTOS [Bar10] et d’une tâche effectuant des appels aux primitives

du RTOS. Par rapport à l’objectif d’étudier un hyperviseur, cette solution matérielle et logicielle

a l’avantage d’être peu coûteuse mais néanmoins de valider notre approche. Elle est également

reproductible et est un système bien plus répandu que les systèmes spécifiques au domaine spatial.

Les primitives de FreeRTOS étudiées sont un sous-ensemble de 13 primitives :

Taches : create, delete, setPriority, suspend, resume ;

Ordonnanceur : getState ;

Semaphores : createBinary, createCounting, createMutex, createRecursiveMutex, delete ;

Mémoire : malloc, free.

Celles-ci sont utilisées par lesbenchmarks. LesbenchmarksdeMälardalen[GBEL10] étudiés,

vi-sibles dans le tableau 5.1, sont sur de petits systèmes allant du Renesas H8300 au ARM9. Cette suite

de benchmarks permet l’expérimentation des algorithmes de mesure du WCET dynamique. Dans

ce papier, nous ne présentons les résultats que sur un sous-ensemble des benchmarkschoisies pour

mettre en évidence les propriétés des algorithmes génétiques et leurs défauts. Nous développons

13. www.mbed.com

plus particulièrement deux algorithmes génétiques et un algorithme aléatoire sur la plate-forme

étudiée.

Techniquement, une connexion relie le MBED via USB à l’ordinateur réalisant les calculs de

l’al-gorithme génétique. Un ordinateur exécute une version de l’all’al-gorithme génétique de Gross [Gro03]

et demande via USB l’exécution de benchmarks avec les paramètres et contextes générés. Après

deux exécutions duditbenchmark, la réponse du MBED est donnée sous la forme d’une trame

com-prenant le rappel du benchmark utilisé, la couverture de code dans le cas de notre apport explicité

par la suite, ainsi que le temps d’exécution mesuré en interne par le MBED. La reproductibilité se

limite donc aux capacités du MBED et aux fonctions testées.

Benchmark S L N A B U Octets LOC

adpcm X 26852 879

compress X X X 13411 508

duff X X X 2374 86

matmult X X X X 3737 163

edn X X X X X 10563 285

Table5.1 – Tableau des benchmarksdeMälardalen utilisés

Légende : S = programme sans dépendance de flot ou de variable externe. L = contient des

boucles. N = contient des boucles imbriqués. A = utilise des tableaux et/ou matrices. B = utilise

des bits d’opérations. U = contient du code non structuré. Octets = taille du fichier de code source.

LOC = lignes dans le code source.

L’évaluation sur la plate-forme physique est découpée en trois étapes :

— l’étude d’un algorithme de recherche aléatoire n’influençant que les paramètres de la fonction

testée ;

— l’application de l’algorithme génétique de Gross tel que décrit en 2003, que nous appellerons

SA pour Sans Apport dans la suite du document. L’algorithme génétique de Gross [Gro03]

est la base des algorithmes génétiques que nous testons sur cette plate-forme. Celle-ci nous

a permis de tester et valider nos apports détaillés par la suite ;

— la comparaison avec un apport de notre part sur celui-ci, que nous appellerons AA pour

Avec Apport dans la suite du document.

L’algorithme aléatoire ne cherche pas à optimiser le problème et offre des valeurs

pseudo-aléatoires à la fonction testée, ici un benchmark. L’algorithme génétique de Gross, lui, optimise le

code et cherche à maximiser le temps d’exécution du système en trouvant des paramètres optimaux.

L’algorithme génétique fonctionne tel que décrit dans 5.4.

Notre apport

Notre apport vient de l’idée du multi-critère. Nous avons testé l’intérêt de modifier l’algorithme

génétique pour y intégrer un nouveau paramètre, c’est-à-dire celui de la couverture de code.

L’idée vient de travaux récents sur l’amélioration de la recherche du WCET par algorithme

génétique. Une nouvelle technique basée sur la capture de l’état d’exécution par méthode dynamique

durant l’évaluation est proposée pour améliorer la probabilité de découvrir des populations de

de cache et nombre d’itération des boucles logicielles) combiné avec le temps d’exécution dans la

fonction defitnessde l’algorithme génétique.

L’algorithme génétique modifié ici utilise la couverture de code, en supplément du temps

d’exé-cution dans la fonction de fitness. L’idée est d’étendre l’espace de recherche en maximisant les

chemins avec un fort impact sur le temps d’exécution.

Pargas et al. [PHP99] a proposé de guider l’optimisation avec la couverture de code et plus

précisément la couverture de branche en utilisant un graphe de dépendance de contrôle. De plus,

Whitten [Whi98] a utilisé l’algorithme génétique pour trouver un sous-ensemble de tests améliorés

par la couverture de code qui emploie unfitness basé sur le temps d’exécution et l’observation des

branches d’exécutions.

En outre, Bueno et Jino [BJ00] ont étudiés l’algorithme génétique pour identifier les chemins

inacessibles d’un programme via une fonction de fitness basée sur le contrôle des informations

de flots et de données. Les résultats sur l’analyse des benchmarks démontrent que l’algorithme

génétique de base de Gross [Gro03] a obtenu 100% de la valeur maximale recherchée avec seulement

10% de branches infaisables comparativement à l’algorithme aléatoire qui n’a trouver que 70% de

la valeur finale. Ces résultats peuvent être encourageant sur un système simple.

D’un point de vue électronique, Smith et al. [SBF97] propose de générer des tests qui

véri-fient l’implémentation électronique d’un microprocesseur en VHDL (langage de description

élec-tronique). Il a trouvé que, comparativement à une méthode aléatoire, la distribution offerte par

l’algorithme génétique est stable et que le résultat obtenu est significativement supérieur à

l’ap-proche aléatoire.

A propos de l’utilisation de la couverture de code dans l’algorithme génétique pour la recherche

du WCET d’une fonction logicielle, Tlili et al. ont proposé de distribuer l’algorithme avec une

population présentant une couverture de code de haut niveau [TSWW06]. Mais cette technique

n’utilise la couverture de code qu’au début de l’algorithme génétique, plus précisément dans la

population initiale. Ceci ne permet que d’améliorer celui-ci au démarrage. Cette absence dans

l’itération de l’algorithme génétique limite son impact.

Nous avons décidé, dans cette thèse, d’évoluer l’algorithme génétique de Gross [Gro03] avec la

couverture de code dans la fonction defitness. Plus précisément, nous décomposons le code en n

blocs de bases avec i∈[0, n[ . Un bloc de base, communément utilisé dans l’analyse statique, est

défini ici comme une unité élémentaire de code avec un seul et unique point d’entrée et une sortie

unique. Pour un chromosome C contenu dans la population P, chaque bloc de base est associé à

un nombre (integer en anglais)∆i(c)représentant le nombre d’exécution de chaque bloc de basei

durant l’évaluation du chromosomec. Cette couverture de code est reliée à chaque chromosome c

au coté du temps d’exécution mesurét(c). L’intérêt de chaque chromosome est basé sur la fonction

defitness suivante :

cost(c) =αt(c)

maxjP t(j)+β

Pn

i=0∆i(c)

maxjP Pn

i=0∆i(j)

Cette technique ne répond pas exactement à notre problème puisque nous utilisons l’accès

au code source. Néanmoins nous avons implémenté notre approche en modifiant un compilateur,

démarche plus aisée que la réécriture du fichier binaire. Ceci dit, nous pourrions tout de même

modifier le fichier binaire et obtenir un résultat parfaitement identique. L’analyse du binaire est

un cas envisageable dans le monde industriel. Cette modification coûteuse en temps et en hommes,

spécifique à un matériel, n’a pas été réalisé dans cette thèse afin de se concentrer sur d’autres