• Aucun résultat trouvé

Chapitre I : Etat de l’art

I.5. Identification des données critiques

Les données manipulées par un programme peuvent être altérées pendant leur stockage en mémoire. Pour détecter les erreurs qui peuvent les frapper, il est possible de les dupliquer comme nous l’avons vu dans le paragraphe I.1.3. mais le surcoût mémoire est alors très important et la comparaison systématique réduit fortement les performances. Il est donc plus judicieux de sélectionner les variables les plus critiques et de ne vérifier que celles-ci.

La détermination des variables critiques passe par la définition et le calcul de critères de criticité. Ces derniers diffèrent d’une approche à une autre mais certains sont assez récurrents comme la durée de vie (« lifetime ») et le nombre de descendants (« fanout »). Cependant la manière de les calculer n’est pas toujours la même. Nous allons donc résumer ici les principales approches proposées dans la littérature et leurs limitations, que nous chercherons à réduire dans le chapitre suivant.

Une fois les variables jugées critiques identifiées, celles-ci peuvent être par exemple dupliquées dans le programme ou dans une mémoire auxiliaire.

I.5.1. Méthode RECCO [Bens. 00] 

Dans l'approche RECCO, une métrique Poids-fiabilité Dv “reliability weight” est calculée pour

chaque variable en fonction des deux paramètres suivants : la durée de vie de la variable et ses dépendances fonctionnelles.

Pour calculer la durée de vie Dv(v) de chaque variable v, Benso et al. comptent le nombre de lignes de code qui séparent une instruction d’écriture de la dernière instruction de lecture de la même variable ou de la fin de l’exécution du programme. Cette méthode ne prend donc en compte ni la récursivité ni les itérations. Elle néglige également le nombre de cycles nécessaires pour exécuter une instruction donnée en fonction de l’architecture cible et des aléas dus par exemple aux dépendances de données ou aux remplissages de caches.

Le second critère utilisé dans cette méthode est les dépendances fonctionnelles Df. La méthode

utilisée pour calculer ce critère consiste à construire un graphe de dépendance (Variable Dependency Graph - VDG), dont chaque nœud représente une variable et chaque arc

représente la dépendance entre les deux variables. Un arc vi → vj existe si et seulement si vj est

une descendante de vi. Ce graphe est utilisé pour calculer un facteur Df (v).

Il suffit ensuite d’appliquer la formule suivante pour déterminer le paramètre Poids-fiabilité(v) :

+Kw* Poids-Fiabilité(descendants(v))

Dv(v) * Kl = (v) Fiabilité -Poids

Où « Kl » et « Kw » sont des coefficients de normalisation.

Prenons l’exemple d’une permutation entre deux variables (Figure 1-16): Les 3 variables sont inter-dépendantes et il est impossible de conclure si “a” dépend de “b” ou bien “b” dépend de “a”. De ce fait, la formule (1) ne peut être utilisée dans ce genre de situation. Pour résoudre ce problème nous pouvons toujours réduire le graphe pour éliminer les cycles mais cette solution est irréversible et engendre une perte d’informations pour les calculs à venir.

Figure 1-16 : Exemple de VDG

I.5.2. Métriques de criticité pour le placement stratégique de détecteurs 

[Patt. 09] 

Pour représenter le plus fidèlement possible les dépendances entre les variables, la méthode de

[Patt. 09] se base sur la construction d’un graphe de dépendance (Direct Dependency Graph -

DDG) à partir du code assembleur et des scenarii d’exécution.

Le DDG est un graphe direct et acyclique (contrairement au VDG présenté au paragraphe 1.5.1.1). Il capture les dépendances dynamiques entre les différentes valeurs produites pendant l’exécution d’un programme.

Dans les DDG, chaque affectation dynamique d’une variable est traitée comme étant une nouvelle valeur. Une valeur est donc toute variable ou toute adresse mémoire utilisée dans le programme pendant son exécution. Si une variable est réécrite, elle est considérée comme étant une nouvelle valeur. Cette description résout le problème d’interdépendance relevé dans les VDG mais implique un grand surcoût mémoire.

En se basant sur ce DDG, Pattabiraman et al. peuvent calculer plusieurs critères de criticité. En effet, ils ont utilisé deux critères classiques, la durée de vie ainsi que le fanout, mais ils ont de plus défini de nouveaux critères à savoir l’exécution, la propagation et la couverture :

La durée de vie est la distance maximale entre un nœud et son successeur immédiat en

termes d’instructions dynamiques,

Le fanout d’un nœud est l’ensemble de tous les successeurs immédiats de ce nœud dans

L’exécution est la fréquence d’exécution des instructions statiques associées à des nœuds,

Le taux de propagation d’une erreur pour un nœud donné est le nombre de nœuds qui

peuvent être affectés par cette erreur avant de causer un crash,

La couverture est le nombre de nœuds à partir desquels une erreur peut se propager

vers un nœud donné avant de causer un crash.

Les principales limitations de cette méthode résident dans la nécessité d'une exécution de l'application pour générer le DDG, et la dépendance potentielle de celui-ci vis-à-vis des valeurs d'entrée utilisées lors de cette exécution. D'autres limitations peuvent être citées au sujet de l'article : le fait que pour déterminer les variables critiques, une seule métrique est utilisée à la fois (absence de formule qui regroupe plusieurs critères de criticité), en plus de l’absence de méthodes automatisées pour calculer ces différentes métriques.

I.5.3. Analyse statique pour l’atténuation des erreurs logicielles dans le 

banc de registres [Lee 09][Lee 11] 

[Lee 09] propose une analyse statique pour estimer la vulnérabilité du banc de registres afin

d’atténuer les erreurs logicielles. La vulnérabilité (Register File Vulnerability) est une sorte de calcul de durée de vie, difficile à réaliser, car il dépend des chemins suivis pendant l’exécution. Cette dépendance est analysée au niveau des blocs, ce qui permet de décomposer la

vulnérabilité d’un bloc entre vulnérabilité intrinsèque vi et vulnérabilité conditionnelle vc, vi

étant la moyenne des longueurs des intervalles fermés dans le bloc [écriture-lecture d’une

variable], et vc la longueur moyenne des derniers intervalles non fermés. Combinant ces deux

paramètres avec les probabilités post-condition S, le taux du RFV est obtenu par la formule suivante :

∑j fjVj = ∑j fj(vij+ vcj Sj)

où fj et Vj sont respectivement la fréquence d’exécution et la vulnérabilité du jième bloc.

Une fois les registres critiques (ou vulnérables) identifiés, ils doivent être sécurisés. Les approches classiques de sécurisation des registres, sélectionnent les registres les plus critiques et ensuite les sécurisent avec des solutions logicielles et/ou matérielles comme la redondance, la

parité… L’approche proposée dans [Lee 10] procède différemment : elle sécurise de manière

matérielle les K registres du banc de registres ayant les numéros les plus grands. Ensuite elle déplace (swapping) les registres les plus critiques de l’application dans les K registres sécurisés par une phase de réallocation des registres.

Le choix d’une solution hybride permet de minimiser les coûts en énergie consommée. Néanmoins, la solution est très liée au jeu d’instructions de l’architecture cible puisque la phase de réallocation se fait sur un exécutable.

I.5.4. Calcul de l’ « Importance » des variables [Leek. 10] 

Trois nouvelles métriques de calcul de criticité des variables ont été présentées dans [Leek. 10] :

l’impact spatial, l’impact temporel et l’importance, la dernière étant obtenue par la fusion des deux premières :

L’impact spatial d’une variable « v » représente la propagation de l’erreur dans les

fonctions adjacentes si « v » est corrompue,

L’impact temporel de « v » indique la durée maximale de l’exécution pendant laquelle

le programme est affecté si « v » est corrompue.

Une fois les calculs faits, deux seuils d’importance sont définis en fonction des résultats

trouvés : λd seuil d’importance des variables à dupliquer et λt seuil d’importance des variables à

tripliquer [Leek. 11].