• Aucun résultat trouvé

Chasse aux Bogues en utilisant FAIL-MPI

7.3 MPICH-V

7.3.7 Chasse aux Bogues en utilisant FAIL-MPI

Fig. 7.24 Impact des fautes simultanées : scénario pour P1

La gure 7.25 présente le pourcentage d'expériences boguées et la moyenne du temps

total d'exécution pour 6 experiences. On peut voir que pour une injection de 5 ou 6

fautes simultanées toutes les 50s, un tiers des expériences ont un comportement bogué.

Une analyse complète des traces des exécutions démontre que toutes ces exécutions étaient

gelées durant la phase de reprise après une injection de fautes. Ce phénomène n'apparaît

pas spontanément avec moins de fautes simultanées, et une majorité des exécutions

n'é-taient pas sujettes à ce comportement, même avec de nombreuses phases de checkpoint

et reprise (une vague de checkpoint est déclenchée toutes les 30 secondes, ainsi il y avait

une moyenne de 6 à 7 vagues de checkpoint avec une injection de fautes toutes les 50

secondes, donc approximativement 4 fautes entraînant une reprise par exécution).

7.3.7 Chasse aux Bogues en utilisant FAIL-MPI

An de localiser précisément le bogue de MPICH-Vcl avec FAIL-MPI, nous avons

exécuté un ensemble d'expériences visant à dénir plus precisément la conguration

en-traînant ce comportement. Comme les traces des exécutions suggéraient que le bogue

se manifestait lors de la reprise après la détection d'une faute, nous avons tout d'abord

construit un scénario pour injecter des fautes pendant ce moment. Le scénario que nous

avons utilisé est formellement donné par la gure 7.26.

Fig. 7.25 Impact des fautes simultanées : résultats

A cause de la complexité du scénario, nous avons modié le scénario générique utilisé

par les n÷uds de calcul. Ils doivent maintenant compter le nombre de vague de restart,

et envoyer un message waveok au processus de contrôl (P1) pour synchroniser l'injection

de fautes. De manière générale, l'algorithme pour le démon P1 est pratiquement le même

que celui utilisé pour les expériences de l'étude de l'impact de la fréquence de l'injection

de fautes. Les lignes 1 à 6 sont utilisées pour assurer que la première faute est réellement

injectée, car nous avons alloué plus de machines que nécessaires pour l'expérience, an

d'avoir des n÷uds de réserve. Un n÷ud participant peut ne pas exécuter un démon MPI,

et l'accusé de réception positif doit être reçu pour assurer qu'une faute a, en eet, été

injectée. Ensuite, le démon P1 attend un message de la part d'un démon FAIL-MPI

exécuté sur un n÷ud de calcul ce qui dénote le début d'une vague de reprise, et lui envoie

un ordre de crash (line 7). Après avoir envoyé cet ordre, il se place dans un état vide

(node 4) et n'injecte plus aucune autre faute pendant l'exécution de l'expérience.

Daemon ADV1 {

node 1 :

1 always int ran = FAIL_RANDOM(0,52) ;

2 time_g timer = 50 ;

3 timer -> !crash(G1[ran]), goto 2 ;

node 2 :

4 always int ran = FAIL_RANDOM(0,52) ;

5 ?ok -> goto 3 ;

6 ?no -> !crash(G1[ran]), goto 2 ;

node 3 :

7 ?waveok -> !crash(FAIL_SENDER), goto 4 ;

node 4 :

}

Fig. 7.26 Impact des fautes synchronisées : scénario pour P1

même si nous injectons seulement 2 fautes en utilisant ce scénario, pour toutes les échelles,

quelques experiences ne se sont pas terminées à cause d'un bogue dans l'implantation de

la tolérance aux fautes. Cela démontre que le bogue est localisé dans cette partie de

l'exé-cution et n'est pas une conséquence de la taille de l'application. Cependant, une large

majorité des exécutions n'est pas sujette au bogue. Nous avons donc déni plus

précisé-ment les conditions de l'injection de fautes. A cette étape de l'étude, nous soupçonnions

que le bogue se produisait seulement si un processus était sujet aux fautes alors qu'il

participait à une vague de reprise pendant qu'un des autres processus n'avait pas ni

de terminer son execution suite à la détection d'une faute. Dans ce cas, le dispatcher

MPICH-Vcl détecte la défaillance d'un processus dans la nouvelle vague. Il semble que si

cela se produit, il n'arrive plus à discerner l'état des processus et lesquel devraient être

relancés.

An de démontrer cela, nous avons considéré un dernier scénario de fautes. Dans cette

expérience, nous voulions exécuter le même scénario que celui utilisé dans l'expérience

précédente mais en utilisant l'état des démons MPI pour déterminer le moment où injecter

la seconde faute. Comme nous voulions nous assurer que le dispatcher MPICH-Vcl n'arrive

plus à distinguer l'état du processus de la vague de reprise, nous devions injecter la faute

après que la connexion a été établie et que quelques unes des communications initiales ont

été faites. Ainsi, la seconde faute a été injectée juste avant que le démon de communication

Fig. 7.27 Impact des fautes synchronisées : résultats

MPI fasse appel à la fonction localMPI_setCommand. Cette fonction est appelée par le

démon de communication après avoir échangé les arguments initiaux avec le dispatcher.

Cela assure que le dispatcher considère ce démon comme correctement initialisé, ainsi il

déclenchera le mécanisme de détection de fautes quand une faute sera injectée.

Le démon FAIL-MPI spécique (P1) utilisé pour coordonner l'injection de fautes est

décrit dans la gure 7.28. La seule modication comparée au scénario de fautes précédent

est que lorsqu'il est dans le n÷ud 4, le processus P1 envoie un ordre nocrash, pour que les

processus non destinés à être victimes d'une faute ne soient pas bloqués avant l'exécution

de la fonction localMPI_setCommand. Le n÷ud 4 a été modié, car après avoir envoyé

un ordre de crash au premier démon de la vague de reprise, le démon P1 doit toujours

attendre les messages de tous les autres démons de la deuxième vague (i.e vague de reprise)

pour leur envoyer un message leur permettant de continuer leur exécution (line 8). Ainsi,

seulement le processus ayant reçu l'ordre de crash (le premier de la vague de reprise a

avoir contacté le dispatcher) sera victime d'une faute juste avant d'exécuter la fonction

localMPI_setCommand.

Daemon ADV1 {

node 1 :

1 always int ran = FAIL_RANDOM(0,52) ;

2 time_g timer = 50 ;

3 timer -> !crash(G1[ran]), goto 2 ;

node 2 :

4 always int ran = FAIL_RANDOM(0,52) ;

5 ?ok -> goto 3 ;

6 ?no -> !crash(G1[ran]), goto 2 ;

node 3 :

7 ?waveok -> !crash(FAIL_SENDER), goto 4 ;

node 4 :

8 ?waveok -> !nocrash(FAIL_SENDER), goto 4 ;

}

Fig. 7.28 Fautes synchronisées basées sur l'état de MPI : scénario pour P1

Les mesures obtenues sont présentées dans la gure 7.29. Dans tous les cas, toutes

les expériences sont gelées pendant la vague de reprise. Ainsi, nous avons conclu que le

bogue dans le processus de reprise illustré par l'injection de fautes simultanées apparaît

quand le dispatcher détecte la défaillance d'un processus déjà dans une phase de reprise,

alors qu'il y a toujours d'autres processus de la vague d'exécution précédente qui n'ont

pas reçu l'ordre de terminaison.

7.3.8 Conclusion

Dans cette section, nous avons utilisé FAIL-MPI pour mettre sous tension

l'implanta-tion du protocole de Chandy-Lamport non bloquant MPICH-Vcl. Nous avons présenté les

modications apportées à la version précédente de l'outil d'injection de fautes FAIL-FCI.

Nous avons ensuite évalué les propriétés de tolérance aux fautes de MPICH-Vcl grâce à

plusieurs expériences utilisant le benchmark NAS BT dans le framework MPICH-Vcl.

FAIL-MPI est la première version de FAIL qui permet à l'application testée de

dy-namiquement lancer et stopper des processus pendant l'exécution. Pour cela, nous avons

ajouté de nouveaux événements speciques au langage FAIL (création, terminaison et

interruption d'un processus). En utilisant cet outil, nous avons été capable de reproduire

Fig. 7.29 Fautes synchronisées basées sur l'état de MPI : résultats

automatiquement des mesures qui étaient auparavant faites manuellement, comme

l'é-tude de l'impact de la fréquence des fautes sur le temps d'exécution [52]. Cela fournit

l'opportunité d'évaluer plusieurs implantations diérentes à des échelles importantes et

de les comparer équitablement avec les mêmes scénarios de fautes.

Les mesures de temps d'exécution démontrent une grande variance dépendante de la

diérence entre la dernière vague de checkpoint et l'injection de fautes. An de fournir

une variance plus faible des résultats, le langage FAIL et l'outil FAIL-MPI devrait être

capable de lire et de modier des variables internes de l'application testée.

Les dernières expériences de la section démontrent la puissance d'expressivité de

FAIL-MPI permettant ainsi la localisation précise d'un bogue apparaissant très rarement dans

le dispatcher de MPICH-Vcl. Nous avons été capable de démontrer que si une seconde

faute frappe un processus faisant déjà partie d'une phase de reprise après qu'il se soit

enregistré avec le dispatcher, et qu'au moins un autre processus de la vague précédente

soit toujours en exécution, alors le dispatcher ne peut plus distinguer l'état de chaque

processus et oublie de lancer au moins un n÷ud de calcul. Ce bogue, qui a été découvert

durant ces expériences, a été corrigé dans la nouvelle version de MPICH-Vcl.

FAIL-MPI est un outil adapté à la détection et l'isolation de bogues, ainsi qu'à

l'é-valuation de performance d'un système distribué complexe tolérant aux fautes sous des

conditions précises d'apparition de fautes.