• Aucun résultat trouvé

1.2 Notre approche

1.2.2 Intégration dans un flot de conception

Le flot de conception, suivant lequel l’application est transformée d’un modèle à l’autre, est re- présenté en FIG.1.1. Dans l’idée, il s’inspire de celui des projets Compaan et Pn : à partir d’un nid de boucles, nous construisons un modèle polyédrique, puis un réseau de processus. Si les premières moitiés des deux flots sont identiques, les deux différences majeures se situent au niveau du réseau de processus et du circuit généré. Notre flot se décompose comme suit :

Décomposition analytique, analyse des bornes et dépendances

Un nid de boucles ne peut pas être transposé tel quel dans le modèle polyédrique, il doit d’abord subir plusieurs transformations intermédiaires. Il est tout d’abord transformé en un arbre de syntaxe abstraite, puis sous forme à assignation unique. De cette façon, les dépendances de données induites par les réécritures dans les mêmes variables sont éliminées. Ensuite, une analyse des domaines de définition des variables et de leurs dépendances est nécessaire, afin de construire les polyèdres corres- pondants.

Différents outils permettent de construire un modèle polyédrique à partir d’un nid de boucles : e.g.

MatParser (utilisé par Compaan) [131,132], Clan [19] ou LooPo [107].

Extraction du parallélisme, transformations linéaires

L’extraction du parallélisme s’effectue au sein du modèle polyédrique. Pour cela, nous recher- chons les transformations linéaires à appliquer au modèle : il nous faut distinguer les opérations devant être effectuées en séquence, à cause d’une relation de dépendance, de celles pouvant être effectuées simultanément.

La première étape consiste à borner l’ensemble des transformations valides, à savoir celles qui respectent les contraintes imposées par les domaines de définitions et les dépendances de données.

Ensuite, nous y recherchons la meilleure transformation possible, selon une métrique. Cette mé- trique est exprimée sous la forme d’une fonction linéaire, à un certain critère (e.g. tailles des mémoires, débit du système, etc). Le choix de la transformation revient donc à résoudre un problème de recherche opérationnelle, où l’on calcule la transformation permettant de maximiser ou minimiser la métrique.

Réseau de processus

Nid de boucles, partie à contrôle statique

Système d’équations récurrentes affines Modèle polyédrique (cf. chapitre4) Graphe à routage k-périodique (cf. chapitre3) Langage synchrone, HDL Décomposition analytique,

analyse bornes et dépendances

Extraction du parallélisme, transformations linéaires

(cf. chapitre4)

Projection sur nœuds de calcul, construction du routage (cf. chapitre5) Transformations non-linéaires, ordonnancement, dimensionnement mémoires (cf. chapitre3)

Conception insensible aux latences, génération de code

(cf. chapitre6)

Entrées

Sorties

Le problème est alors résolu par un solveur de programme linéaire en nombres entiers. Cette technique de parallélisation et d’optimisation a montré son efficacité au travers des nombreux travaux dont elle fut l’objet [32,86,104,108,151,152,181,224].

Projection sur nœuds de calcul, construction du routage

Le parallélisme extrait du modèle polyédrique infère un certain nombre de sous-ensembles d’opé- rations pouvant être exécutées simultanément. Grâce à cela, nous projetons ces opérations sur un graphe à routage k-périodique : chaque opération y est associée à la production d’un jeton par un nœud de calcul. Ainsi le parallélisme d’instruction et de données y est explicitement représenté.

L’interconnexion entre nœuds de calcul est déterminée selon les dépendances de données : si deux opérations dépendent l’une de l’autre, alors il existe un chemin correspondant dans le KRG, permettant d’acheminer un jeton d’un nœud de calcul à l’autre.

Une première différence entre notre approche et Compaan réside dans le niveau d’abstration des réseaux de processus (KRG dans notre cas, SBF pour Compaan) lors de leur construction à partir du modèle polyédrique.

Par exemple, pour calculer les valeurs de quatre tableaux multidimensionnels, Compaan construit un graphe SBF à quatre nœuds de calcul : chaque nœud de calcul correspond à un nid de boucles séquentielles permettant le parcours d’un tableau. Et ce, même si plusieurs cases du tableau peuvent être calculées simultanément ; cela revient à perdre une partie du parallélisme extrait du modèle poly- édrique. Dans le flot de conception de Compaan, cela correspond à l’étape de linéarisation [132,225]. Autrement dit, le graphe SBF ainsi généré n’exploite que du parallélisme d’instruction : deux instruc- tions indépendantes peuvent être évaluées en parallèle.

Dans notre cas, nous pouvons construire un KRG contenant autant de nœuds de calcul que le nombre maximum de cases de tableau pouvant être calculées simultanément. C’est-à-dire qu’en plus du parallélisme d’instruction, nous exploitons également le parallélisme de données : si deux occur- rences d’une même instruction sont indépendantes, alors elles peuvent être évaluées en parallèle.

Transformations non-linéaires, ordonnancement, dimensionnement des mémoires

Les propriétés algébriques des KRG permettent d’affiner les résultats des transformations linéaires du modèle polyédrique. Tout d’abord, nous pouvons appliquer des transformations topologiques vi- sant à « équilibrer » les flots de jetons au sein du KRG, tout en préservant sa fonctionnalité. Par exemple, certains nœuds de calculs peuvent être plus ou moins utilisés à l’exécution ; il est alors utile, selon le cas de figure, de (i) rerouter des jetons d’un nœud de calcul vers un autre pour équilibrer leur charge, (ii) fusionner plusieurs nœuds de calcul peu utilisés en un seul, et entrelacer les flots, ou au contraire (iii) dupliquer un nœud de calcul et éclater les flots de façon à alléger la charge de chacun. Ces différentes optimisations permettent d’optimiser localement le réseau de processus.

Le fait d’associer aux nœuds de calcul une règle de production et consommation au plus tôt confère au graphe une sémantique n-synchrone. Du fait que le routage des jetons est sans conflit et ul- timement périodique, et que nous considérons des latences constantes, le graphe peut être ordonnancé statiquement. Les capacités des mémoires peuvent alors être dimensionnées de façon optimale.

Conception insensible aux latences, génération de code

Enfin, le KRG synchrone peut facilement s’exporter vers un programme synchrone, et en particu- lier n-synchrone. Les nœuds de calculs du KRG se comportent alors comme des modules synchrones. La réécriture en Lucy-n [157], par exemple, est immédiate.

Les nœuds de calculs peuvent se trouver désynchronisés lorsque les latences de communications ne permettent pas d’acheminer les données de l’un à l’autre en l’espace d’un cycle d’horloge. Pour cette raison nous appliquons au KRG une méthodologie dite de conception insensible aux latences. Cette méthodologie garantit la préservation de la fonctionnalité de l’application. Son comportement est alors globalement asynchrone, et localement synchrone.

L’implantation du LID peut se faire soit par le biais d’un protocole dynamique, soit par ordon- nancement statique. Dans le premier cas, le protocole coupe l’horloge des modules qui ne disposent pas de données à l’ensemble de leurs entrées, et rétropropage un signal d’arrêt en cas de congestion. Dans le second cas, les ordonnancements des nœuds sont calculés statiquement à la compilation. Un contrôleur, faisant office d’oracle, active et désactive les nœuds lorsque nécessaire.

Documents relatifs