• Aucun résultat trouvé

code SML

Chapitre 2 Le projet SKiPPER : SKiPPER-I

2.2 Le jeu de squelettes

2.2.2.1 Le squelette SCM (Split, Compute and Merge)

Ce squelette regroupe les sch´emas de parall´elisme d´edi´es au traitement g´eom´etrique des donn´ees. Son fonctionnement est le suivant.

La donn´ee d’entr´ee (typiquement une image) est tout d’abord divis´ee en un nombre fixe d’´el´ements par la fonction utilisateur affect´ee `a la phase split du squelette. Chaque ´el´ement ainsi obtenu est alors trait´e de mani`ere totalement ind´ependante par une fonction utilisateur r´ealisant la phase compute du squelette. L’ensemble des r´esultats des traitements sont alors ensuite regroup´es pour former un r´esultat d´efinitif de l’application de ce squelette. Ce r´esultat est une combinaison des r´esultats interm´ediaires. La nature de la combinaison est laiss´ee `a la discr´etion de l’utilisateur par l’interm´ediaire de la fonction assign´ee `a la phase merge du squelette.

Ce squelette est dit statique, c’est-`a-dire que son sch´ema de communication est enti`e-rement connu `a la compilation. On notera aussi que, si chaque fonction compute doit ˆetre plac´ee sur un processeur diff´erent pour obtenir une parall´elisation r´eelle des traitements, la s´e-quentialit´e dans l’enchaˆınement des fonctions split, compute et merge permet de placer sur un mˆeme processeur ces trois fonctions (une seule instance de la fonction compute en l’occurence).

Il faut bien noter que, du fait de sa nature mˆeme, ce squelette impose :

– qu’une mˆeme fonction utilisateur joue le rˆole de la phase compute (plusieurs fonctions distinctes ne peuvent ˆetre utilis´ees simultan´ement),

– que les dur´ees des traitements ne soient pas (trop) d´ependantes des donn´ees afin de ga-rantir que toutes les processeurs finiront leurs traitements au mˆeme moment.

Ce dernier point est primordial pour garantir l’efficacit´e du squelette SCM. Dans le cas contraire des processeurs consommeraient du temps `a attendre la fin des traitements sur d’autres processeurs. Le sch´ema de parall´elisation ne serait alors plus ad´equat, le d´es´equilibre de charge devenant trop important.

La figure 2.1 est un synoptique du squelette SCM auquel correspond la s´emantique

d´ecla-rative (en Caml) ci-dessous2. Nous entendons par s´emantique d´eclarative, celle utilis´ee pour permettre au programmeur de comprendre le rˆole d’un squelette en dehors de toute consid´era-tion architecturale. Elle peut ˆetre consid´er´ee comme l’interface du squelette.

> let scm split compute merge x =

merge ( map compute ( split x ) )

A cette s´emantique d´eclarative correspond la signature suivante (qui ´etablit notamment le type des fonctions qui seront pass´ees en arguments du squelette) :

# val scm :

(’a -> ’b list) (* fonction de division *)

-> (’b -> ’c) (* fonction de traitement *)

-> (’c list -> ’d) (* fonction de fusion *)

-> ’a (* donnee *)

-> ’d (* resultat *)

La figure 2.2 donne quant `a elle un exemple d’ex´ecution (placement et ordonnancement) du squelette SCM sur une architecture a quatre processeurs.

Les algorithmes vis´es par ce squelette sont donc, dans le domaine du traitement d’images, les algorithmes bas niveau de pr´e-traitement tels que :

- convolutions, - filtres,

- histogrammes.



Se reporter `a l’annexe A page 177 pour un compl´ement d’information sur la syntaxe Caml de la s´emantique pr´esent´ee.

Y3 SPLIT(X)=(X1,...,Xn) Yi=COMPUTE(Xi) X Y=MERGE(Y1,...,Yn) X3 Xn X1 Y1 Y2 Yn X2 Y FIG. 2.1 – Synoptique du squelette SCM.

COMPUTE COMPUTE COMPUTE COMPUTE

P3 (esclave) SPLIT MERGE X X0 X1 X2 X3 Y0 Y1 Y2 Y3 Y

P0 (maitre) P1 (esclave) P2 (esclave)

2.2.2.2 Le squelette DF (Data Farming)

Le squelette DF sert `a appliquer en parall`ele une fonction `a tous les ´el´ements d’une liste de donn´ees et `a combiner les r´esultats. Il a ´et´e sp´ecialement con¸cu pour g´erer les cas o`u, soit le temps de traitement des donn´ees par les processeurs n’est pas uniforme, soit le nombre de donn´ees `a traiter n’est pas connu `a l’avance, voire les deux `a la fois. Le temps de calcul d´epend alors directement des donn´ees qui sont manipul´ees. C’est notamment le cas lorsque les algo-rithmes de vision artificielle ne se contentent plus de traiter des images brutes mais des indices visuels (polygˆones, segments,...), souvent sous forme de listes d’objets [Can93] [Cou97]. Un m´ecanisme d’´equilibrage de la charge de calcul des processeurs est alors n´ecessaire. Le sque-lette DF r´epartit dynamiquement les donn´ees d’entr´ee sur les processeurs pour traitement, tout en r´ealimentant les processeurs qui auraient fini leur traitement avant les autres.

On notera ici la nature compl`etement dynamique de ce squelette, le temps de traitement d’une donn´ee ´el´ementaire sur chaque processeur ne pouvant ˆetre anticip´e et pouvant ˆetre diff´e-rent de celui obtenu sur d’autres processeurs engag´es dans le mˆeme sch´ema de parall´elisation.

En r´esum´e, la principale diff´erence entre les squelettes SCM et DF est que le premier en-capsule un parall´elisme de donn´ees fixe alors que pour le second il s’agit d’un parall´elisme de donn´ees variable.

Ce sch´ema utilise pour son implantation un mod`ele d’ex´ecution en ferme de processeurs. Un processeur est d´esign´e comme maˆıtre, les autres comme esclaves. Le maˆıtre est charg´e de distribuer les donn´ees `a traiter aux esclaves. G´en´eralement le nombre de donn´ees initiales destin´ees au traitement ´etant sup´erieur au nombre d’unit´es de calcul disponibles sur la machine cible, le maˆıtre garde en r´eserve un certain nombre de donn´ees lorsque tous les esclaves ont ´et´e servis. D`es que l’un d’entre eux signale qu’il a termin´e son traitement en renvoyant le r´esultat au maˆıtre, ce dernier r´ealimente l’esclave avec une nouvelle donn´ee pour le maintenir constamment en charge et ainsi r´ealiser dynamiquement l’´equilibre de charge du r´eseau de processeurs.

Les r´esultats en provenance des esclaves s’accumulent au niveau du maˆıtre. La mani`ere dont est effectu´ee l’accumulation est dict´ee par une fonction utilisateur.

On pourra remarquer que l’ordre d’arriv´ee des r´esultats n’est pas forc´ement celui dans le-quel les donn´ees ont ´et´e distribu´ees. Enfin, la fonction de calcul op´erant pour chaque esclave doit ˆetre la mˆeme. Ce squelette, comme le SCM, n’autorise pas des fonctions de calcul diff´e-rentes pour chaque esclave.

La figure 2.3 est un synoptique du squelette DF auquel correspond la s´emantique d´eclarative (en Caml) suivante3:

> let df compute acc z xs =

foldl acc z ( map compute xs )



La signature de ce squelette est :

# val df :

(’a -> ’b) (* fonction de traitement *)

-> (’c -> ’b -> ’c) (* fonction d’accumulation *)

-> ’c (* valeur initiale *)

(* de l’accumulateur *)

-> ’a list (* liste de donnees *)

-> ’c (* resultat *)

La fonction compute, comme dans les autres squelettes, est une fonction fournie par l’utilisa-teur pour traiter les donn´ees individuelles. La fonction acc, aussi fournie par l’utilisal’utilisa-teur, permet d’accumuler les r´esultats partiels en prevenance des traitements sur les diff´erents processeurs esclaves (z est la valeur initiale de l’accumulateur). L’accumulation des r´esultats partiels est r´ealis´ee `a mesure que ceux-ci sont produits d’o`u l’emploi de la fonctionnelle qui permet d’appliquer it´erativement la fonction acc `a la liste de r´esultats (voire l’annexe A page 177 pour l’expression de).

Xi MAITRE

ESCLAVES

ACC Y=ACC(Yi,... ACC(Y,...,Z))

[X1,...,Xn]

Z

COMP COMP COMP COMP

Yi=COMP(Xi) Yi

FIG. 2.3 – Synoptique du squelette DF.

La figure 2.4 donne quant `a elle un exemple d’ex´ecution du squelette DF sur une architecture form´ee de quatre processeurs. Elle repr´esente le traitement par un squelette DF d’une liste de donn´ees `a 6 ´el´ements (X0 `a X5). Puisque 4 processeurs seulement sont disponibles, seuls 3 sont utilis´es comme esclaves et donc r´ealisent le traitement des donn´ees. Le maˆıtre commence par envoyer les 3 premi`eres donn´ees X0, X1 et X2 `a traiter (autant que d’esclaves libres) aux 3 processeurs d´edi´es aux calculs, pour ensuite se mettre en attente du r´esultat des traitements sur ces donn´ees. La premi`ere valeur retourn´ee est Y1 en provenance du deuxi`eme esclave. A ce moment le maˆıtre peut envoyer une nouvelle donn´ee vers cet esclave devenu libre et accumuler ce r´esultat avant de se remettre en attente `a nouveau. Ce processus se renouvelle jusqu’`a ce que toutes les donn´ees initiales soient trait´ees.

Les algorithmes vis´es par ce squelette sont donc, dans le domaine du traitement d’images, des algorithmes dont la complexit´e d´epend des donn´ees, comme par exemple les op´erateurs d’approximation polygonale de chaˆınes de points connexes [GG91] [Leg95] [Cou96]. Ces al-gorithmes exploitent une strat´egie r´ecursive de division de la courbe dont l’arrˆet est conditionn´e par la distance s´eparant la courbe r´eelle et les segments qui en donnent une approximation. Le temps de traitement d´epend ici de la taille et de la forme de la courbe.

[Y0,...,Y5] ACC ACC ACC ACC ACC ACC Z [X0,...,X5]

P0 (esclave 1) P1 (maitre) P2 (esclave 2) P3 (esclave 3) COMPUTE COMPUTE COMPUTE COMPUTE COMPUTE COMPUTE Y3 Y2 Y0 Y4 Y5 Y1 X4 X1 X0 X2 X3 X5

2.2.2.3 Le squelette TF (Task Farming)

Le squelette TF est le plus complexe du jeu de squelettes de SKiPPER.

Ce squelette est similaire au squelette DF, et en reprend d’ailleurs les principales caract´e-ristiques. La seule diff´erence de comportement qu’il introduit, et qui le caract´erise, est le fait que le r´esultat d’un traitement peut ˆetre, ´eventuellement, r´einject´e comme donn´ee d’entr´ee pour subir un nouveau traitement apr`es red´ecoupage en donn´ees plus ´el´ementaires.

En fait, ce squelette peut ˆetre consid´er´e comme un squelette DF g´en´eralis´e en cela que le traitement d’une donn´ee peut ´eventuellement g´en´erer r´ecursivement de nouvelles donn´ees qui seront distribu´ees `a l’it´eration suivante. Comme pour le squelette DF, c’est une ferme de processeurs qui est utilis´ee comme mod`ele d’ex´ecution.

Le maˆıtre du squelette TF a pour rˆole de distribuer les donn´ees `a traiter et de collecter les r´esultats correspondants tout en maintenant l’´equilibre de charge en terme de calcul sur l’ensemble de ses esclaves. Cependant, le traitement op´er´e par les esclaves est un peu plus complexe que l’application d’une simple fonction de calcul `a chaque donn´ee qui se pr´esente. En effet, un esclave commence toujours par appliquer une fonction de pr´edicat sur la donn´ee entrante pour savoir s’il doit ou non appliquer la fonction de calcul. F. Chantemargue dans sa th`ese [Cha91] donne comme exemple de pr´edicats les tests d’homog´en´eit´e des r´egions d’une image (tests obtenus par calculs statistiques de moyenne et d’´ecart-type sur les valeurs valeurs des pixels, une r´egion ´etant d´eclar´ee homog`ene si l’´ecart-type sur les valeurs des pixels est inf´erieur `a un seuil fix´e au pr´ealable). Un exemple d’utilisation du squelette TF avec ce type de pr´edicat est donn´e figure 2.54.

FIG. 2.5 – R´esultat de l’utilisation du squelette TF pour la division r´ecursive d’images.



Se reporter `a la section 5.2.4 page 133 pour une description compl`ete de cet algorithme et l’utilisation du squelette TF pour sa parall´elisation

Si le pr´edicat est vrai, alors la donn´ee est trait´ee localement par l’esclave en lui appliquant la fonction de calcul. Sinon, elle est retourn´ee au maˆıtre qui appliquera une fonction de division afin de g´en´erer `a partir d’elle un nouvel ensemble de donn´ees `a traiter.

La figure 2.6 est un synoptique du squelette TF auquel correspondent la s´emantique d´ecla-rative (en Caml)5et la signature suivantes :

> let rec tf trivial solve divide combine z xs = let f x =

if ( trivial x ) then

combine z ( solve x ) else

tf trivial solve divide combine z ( divide x ) in foldl combine z ( map f xs )

# val tf :

(’a -> bool) (* fonction de predicat *)

-> (’a -> ’c) (* fonction de traitement *)

-> (’a -> ’a list) (* fonction de partition *)

-> (’b -> ’c -> ’b) (* fonction d’accumulation *)

-> ’b (* valeur initiale de l’accumulateur *)

-> ’a (* donnees *) -> ’b (* resultat *) SOLVE TRIVIAL SOLVE TRIVIAL SOLVE TRIVIAL SOLVE TRIVIAL

Yi = if TRIVIAL(Xi) then SOLVE(Xi) else DIVIDE(Xi)

ESCLAVES COMBINE MAITRE Y=COMBINE(... COMBINE(Yi,Z)) X Z Xi Yi

DIVIDE DIVIDE DIVIDE

DIVIDE

FIG. 2.6 – Synoptique du squelette TF.



La figure 2.7 donne quant `a elle un exemple d’ex´ecution du squelette TF sur une architecture form´ee de quatre processeurs. Elle repr´esente le traitement par un squelette TF d’une liste de donn´ees `a 4 ´el´ements (X0 `a X3). Puisque 4 processeurs seulement sont disponibles, seuls 3 sont utilis´es comme esclaves et donc r´ealisent le traitement des donn´ees. Le maˆıtre commence par envoyer les 3 premi`eres donn´ees X0, X1 et X2 `a traiter (autant que d’esclaves libres) aux 3 processeurs d´edi´es aux calculs, pour ensuite se mettre en attente du r´esultat des traitements sur ces donn´ees. La premi`ere valeur retourn´ee l’est sur le calcul de X1. Mais cette donn´ee ne r´epondant pas au pr´edicat, deux nouvelles donn´ees plus ´el´ementaires X11 et X12 sont produites `a partir de X1 et r´eintroduite dans la liste des donn´ees `a traiter au niveau du maˆıtre. Ces donn´ees sont trait´ees lorsque toutes les donn´ees d´ej`a pr´esente dans la file d’attente l’ont ´et´e (gestion en mode FIFO6). X11 ACC ACC ACC ACC ACC

P0 (esclave 1) P1 (maitre) P2 (esclave 2) P3 (esclave 3) COMPUTE COMPUTE COMPUTE COMPUTE COMPUTE COMPUTE Y3 Y2 Y0 Y11 Y12 X1 X0 X2 X3 X12 [Y0,...,Y5] [X0,...,X3] Z [X11, X12]

FIG. 2.7 – Exemple d’ex´ecution sur 4 processeurs du squelette TF.