• Aucun résultat trouvé

5.3 Bilan interm´ediaire

6.1.2 M´emoire et identifiant

Evaluation termin´ee ´ Evaluation incompl`ete arbre d’´evaluation G´en´erateur

Fig. 6.4 – La salle d’attente r´ecup`ere les r´ef´erences des amplifieurs dont l’´evaluation est incompl`ete et attend le bon moment pour les remettre dans le circuit.

visibilit´e

Chargement texture

Affichage Pr´ecision

Animation Cr´eation des enfants

Affichage boite englobante

Fig. 6.5 – Au contact d’un visiteur, un amplifieur peut ex´ecuter diff´erentes fonctions. Celle-ci d´ependent les unes des autres. Par exemple, l’affichage ne peut ˆetre effectu´e qu’apr`es le calcul de l’animation.

G´en´eralement, le g´en´erateur demande la requˆete de complexion `a tous les amplifieurs. La complexion d’un amplifieur entraˆıne souvent la cr´eation de nouveaux amplifieurs qui doivent ˆetre ´evalu´es `a leur tour. Lorsque tous les amplifieurs satisfont la requˆete de complexion, l’´evaluation est termin´ee.

6.1.2 M´emoire et identifiant

Dans Dynamic Graph, chaque arbre d’´evaluation connaˆıt son ancˆetre (notamment pour per-mettre l’optimisation par coh´erence temporelle). Ceci est r´ealis´e grˆace au tampon d’arbres et aux identifiants attribu´es `a chaque noeud. Chaque amplifieur a une date de naissance et de mort d´e-finissant sa dur´ee de vie, notamment utilis´ee pour stocker des informations sur une longue dur´ee. Tampon d’arbres

Le tampon d’arbres stocke les n derniers arbres d’´evaluations. n est fix´e par le cr´eateur ou l’application, selon les besoins de l’un ou de l’autre. Cette valeur peut ˆetre modifi´ee dynamiquement durant l’ex´ecution du programme.

Son impl´ementation est bas´e sur l’utilisation de “tableaux rotatifs”. Ces tableaux sont tout simplement des tableaux normaux dont l’acc`es est rendu cyclique en prenant les index modulo n. Lorsque le programme d´ebute, les premi`eres cases du tableau, initialement vides, sont succes-sivement remplies par un arbre d’´evaluation. Lorsque le tableau est plein, les cases les plus vieilles sont lib´er´ees pour laisser place aux nouveaux arbres.

Chaque arbre d’´evaluation est connect´e `a son ancˆetre (l’arbre du pas de temps pr´ec´edent). La connexion est r´ealis´ee dans les deux sens, ce qui signifie que chaque arbre est connect´e `a son ancˆetre et `a son successeur (s’ils existent).

mort naissance

Vie d’un amplifieur

Temps

t − 2δt

t − 3δt t − δt t

+ r´ecent Tampon d’arbres

Fig. 6.6 – Chaque amplifieur de chaque arbre d’´evaluation stock´e dans le tampon d’arbres a connaissance de son successeur et de son ancˆetre. Ceci lui permet d’avoir acc`es aux informations `a des temps diff´erents (g´en´eralement pass´es).

1 2 0 2 3 0 0 (0, 2, 3) Identifiant global :

Fig. 6.7 – Un identifiant global est une liste d’identifiants locaux repr´esentant le chemin de la racine `a l’amplifieur identifi´e. Un identifiant local est unique parmi les identifiant des amplifieurs fr`eres. Un identifiant global est unique parmi les identifiant des amplifieurs de l’arbre.

Identifiant global

Lorsque l’on dit qu’un arbre est connect´e `a son ancˆetre, cela signifie que chacun de ses noeuds (i.e. amplifieurs) est connect´e `a son noeud ancˆetre (cf. figure 6.6). Cette connexion est r´ealis´ee durant la cr´eation d’un nouvel arbre (c’est-`a-dire durant une nouvelle ´evaluation). Le principe est simple : chaque noeud a un identifiant global le distinguant de tous les autres noeuds d’un mˆeme arbre. Lorsqu’un noeud est cr´e´e, il v´erifie si un noeud du mˆeme identifiant existe dans l’arbre pr´ec´edent : s’il existe, la connexion est cr´e´ee. Ceci baigne chaque amplifieur dans une structure de liste doublement chaˆın´ee.

Une recherche d’identifiant global dans un arbre est une op´eration dont le coˆut n’est pas n´egligeable. Si l’on consid`ere que l’acc`es `a un fils est r´ealis´e en coˆut constant, le coˆut moyen d’une recherche est proportionnel `a la hauteur de l’arbre pr´ec´edent. La r´ealiser lors de la cr´eation de chaque nouveau noeud gr`everait consid´erablement les performances. L’utilisation d’identifiant local permet de palier ce probl`eme.

Identifiant local

Un identifiant local permet de distinguer un amplifieur parmi ces fr`eres. Concr`etement, un identifiant local est un entier non sign´e. Un identifiant global est une liste d’identifiants locaux d´ecrivant le chemin `a suivre pour aboutir au noeud en question (cf. figure 6.7). Chaque noeud de l’arbre contient un conteneur vers ces noeuds fils. Ce conteneur est un conteneur associatif [D’A02] dont la clef (unique) est l’identifiant local. Acc´eder au fils i ∈ N revient donc `a chercher l’existence de cette clef dans le conteneur associatif.

Arbre en construction

´etape 1 ´etape 2 ´etape 3

Arbre pr´ec´edent Pas de successeur Pas d’ancˆetre

Fig. 6.8 – L’ancˆetre d’un noeud est ”le fils de l’ancˆetre de son p`ere”. Cette formulation ne fait intervenir qu’une recherche d’identifiant local, c’est-`a-dire la recherche d’un fils particulier parmi ses fr`eres. Nous verrons en 7.2 que le coˆut de cette recherche d´epend des choix que fait le cr´eateur. Dans le meilleur des cas, elle est effectu´ee en coˆut constant.

Pour les raisons de performance identifi´ees plus haut, les identifiants locaux sont utilis´es pour faire des recherches relatives. Pour comprendre intuitivement le m´ecanisme, on peut le comparer aux chemins de fichiers sous UNIX. Il est en effet souvent plus efficace d’acc´eder `a un fichier par un chemin relatif comme :

”../source/toto.cpp”

que par un chemin absolu comme :

”/home/evasion/perbet/cpp/dg/model/source/toto.cpp”

La recherche de l’ancˆetre est r´ealis´ee au cours de l’´evaluation. Elle est initialis´ee avec la racine du nouvel arbre : celui-ci est sp´ecifiquement connect´e `a la racine de l’arbre pr´ec´edent par l’organiseur. Ensuite, chaque nouvel amplifieur a pour ancˆetre (au sens temporel) ”le fils de l’ancˆetre de son p`ere” (cf. figure 6.8). Comme les connexions sont r´ealis´ees au fur et `a mesure, on est assur´e que le p`ere d’un amplifieur connaˆıt d´ej`a son ancˆetre.

Destruction `

A chaque pas de temps, lorsque le tampon d’arbres est plein, l’arbre le plus vieux est d´etruit. C’est un visiteur particulier qui s’occupe de ¸ca : le destructeur. Celui-ci parcourt l’arbre des feuilles vers la racine en utilisant le retour d’un parcours en profondeur d’abord.

Il d´etruit tous les fils de l’amplifieur qu’il visite (la racine a un traitement particulier). De plus, si l’amplifieur n’a pas de successeur, il appelle sa fonction de mort. Si l’amplifieur `a un successeur, il supprime proprement ce lien (dans les deux sens).

Vie et mort

La figure 6.6 montre la vie et la mort d’un amplifieur. La naissance est par d´efinition une construction sans ancˆetre et la mort une destruction sans successeur. Lors de la naissance (resp. de la mort) d’un amplifieur, un constructeur (resp. un destructeur) sp´ecial est appel´e.

Cette fonctionnalit´e permet d’initialiser de l’amplifieur. Par exemple, une texture peut ˆetre allou´ee lors de la naissance et d´esallou´ee lors de la mort. Plus g´en´eralement, la naissance et la vie d’un amplifieur permet de stocker n’importe quelle information mortelle pendant plusieurs pas de temps. L’information mortelle dure plus longtemps que les informations ´eph´em`eres qui sont stock´ees dans un amplifieur : celles-ci sont accessibles n pas de temps ou n est la taille du tampon d’arbres En revanche, l’information mortelle dure moins longtemps que l’information permanente qui est d´ecrite dans la sous-section suivante.

avec information sans information

Association entre un amplifieur et l’information permanente correspondante

Arbre permanent

t − δt t

Fig. 6.9 – Cette figure montre l’arbre dynamique `a deux pas de temps successif avec, en gris´e, l’arbre permanent. L’arbre permanent ne change pas dans le temps. Les donn´ees permanentes sont associ´ees `a un amplifieur qui, `a un instant donn´e, peut exister ou non. Certains noeuds de l’arbre permanent sont vides et ne servent qu’`a atteindre des noeuds non vides.