• Aucun résultat trouvé

COMMUNICATING REGULAR                      PROCESSES   (CRP)

N/A
N/A
Protected

Academic year: 2022

Partager "COMMUNICATING REGULAR                      PROCESSES   (CRP)"

Copied!
40
0
0

Texte intégral

(1)

      ÉCOLE NORMALE SPERIEURE        DE LYON (E.N.S) 

       

      Mémoire de  Master2 recherche en informatique IF

       COMMUNICATING REGULAR       PROCESSES   (CRP)        

      réalisé par  

      Noureddine HAMADOUCHE.

      Noureddine.Hamadouche@ens­lyon.fr       dirigé par:

       Paul FEAUTRIER

      professeur de l'université versailles (paris)        membre de l'équipe compsys (lyon)        Paul.Feautrier@ens­lyon.fr  Jury:

 ­  ­  ­  ­  ­

  

        Laboratoire Informatique Parallélisme (LIP)

      (Projet Inria :Compsys)       Juin 2006.

(2)

résume: 

le langage CRP est une extension de C destinée à l'écriture de programmes de type 

« traitement de signal », en particulier de flux vidéo  pour systèmes embarqués. Par rapport  au C standard , il comporte des processus , des canaux et des ports.

l'objectif à long terme du projet est d'utiliser un programme CRP comme spécification d'un  accélérateur matériel réalisé à l'aide d'un FPGA (ou d'un ASIC..) .

un programme  CRP ne peut pas être compilé par le compilateur C standard  et encore moins  exécuté. en particulier, les mots­clefs process,inport,outport et channel ne sont pas reconnus  par le compilateur et sont génant car il est impossible de valider un programme CRP avant de  réaliser le circuit correspondant. 

le sujet principal du stage est de réaliser un outil logiciel permettant de transformer un  programme CRP en un programme C++ utilisant les threads et ayant le même 

fonctionnement.

Pour vérifier le bon fonctionnement de cet outil logiciel, on sera amené à enrichir la base  d'exemples du projet syntol, par exemple en important et en adaptant des benchmarks postés  sur le web par des projets analogues (StreamIt..).

Introduction:

La conception d’un système qui traite des  flots vidéos à haute  performance est un domaine  fort , conduit par des marches  comme la TV  de  haut débit,  l'animation 3D et l'image  médicale,les langages de programmation  de ce type d’applications ont été introduits dans le  cadre de la programmation des systèmes réactifs et en temps réel. différents projets sont  destinés à l'écriture des applications de flux vidéo tels que (SANDRA,StreamIt,..) pour  systèmes embarqués.

Le projet   SYNTOL qui est en cours de développement  par l'équipe compsys, il est basé sur  un langage de programmation destiné à l'écriture de ce type d'applications , qui est le CRP  (communicating regular processus) .Le  modèle de communication basé en CRP, c'est le  «   processus et le réseau des processus ». La syntaxe de CRP est la même que le langage C[1],  avec d'autre nouveaux mots clefs « channel,process,inport,outport » qui ne sont pas  définis  par le langage C,par conséquent on ne peut pas compiler un  programme  CRP par un  compilateur C standard. 

Le but dans ce stage est d'implémenter un outil logiciel qui  permet de définir ces  nouveaux  mots clefs (en respectant la sémantique de langage CRP) et de transformer un programme  CRP (après l'analyse lexicale et syntaxique) à un  programme  C++ en utilisant les threads  ayant le même fonctionnement , afin de compiler ce programme  par le compilateur de C  standard.

Dans ce travail on garantie aussi la synchronisation entre les threads pour accéder a l' espace  mémoire partagée (canal) .

Par conséquent , l'outil logiciel réalisé permet d'écrire d'autres applications de  flux vidéo ,  afin d'enrichir la base  des exemples de projet  syntol.

Dans ce rapport , on présente  différents langages et modèles de communication de processus  et réseau de processus,puis on présente le langage CRP et la conception de  notre outil logiciel  en détail, d'autres problèmes et travaux  de recherche dans le domaine seront présentés aussi.

(3)

Plan de travail:

résumé...

Introduction...

I.Généralité...5

  1. les systèmes réactifs...5

   1.1 Déterministe et concurrence...5

Deterministe...5

Concurrence...5

   2.modèle de programmation parallèle...6

évaluation...6

 II.Programmation par échange de message   et le Standard MPI...7

     1.Principe...7

      1.1.Primitives de communications...7

      1.2 canal...7 

    2.Le standard MPI (message passing Interface)...8

    3. inconvénients de MPI...8

III. Modèle KPN (Kahn Process Network)...8

      1.Définition...8

      2.Composants de base...9

       a.Processus...9

       b.Canal...9

       c.Primitives (envoie/reception)...9

     3.Exemple...9

     4.L'intérêt de KPN...10

     5. Limites et inconvénients de KPN...10 

IV.Conception...11

   1.Conception de CRP (communicating Regular Process)... 11

       1.1.Introduction...11

       1.2.Définition...12

       1.3.Composants de base...13

       1.3.1.processus...13

       1.3.2.canal...13

       1.3.3.Ports...13

       1.3.4.Bornitude de canal...13

       1.3.5.exemple commenté...14

           2.Conception de transformation...15

        2.1.Conception de processus...15

        2.2.Les primitives de Synchronisation...15

        2.3.Un canal et sa taille...15

        2.4 Inport/Outport ...16

V.Implémentations...17 

   1.une vue générale sur la transformation...17

   2.Structure de Compilateur...17

   3.  une vue générale sur la syntaxe de transformation...18

       3.1.process... .18

(4)

       3.2.channel...18

       3.3. inport/outport...19

       3.4.boucle infini...19

       3.5. lancement de processus...19

3.6.opérations de ré initialisation...20

   4.contraints...20

   5.exemple de transformation...21

VI.Application...24

      1.la norme MPEG...24

      2.structure  d'une séquence video...24

     3.Description de shéma de codage/stockage...25

Description des processus...25 

VII.Efficacités et Discussion...26

         1. degré de parallélisme...26

         2.syntax de langage...27

         3. consommation de mémoire...27

 IIX. Conclusion...29 Annexe

Bobliographie

(5)

 I.GENERALITE :

1.systèmes Réactifs:On peut schématiquement classer les systèmes informatiques en trois  grandes familles:transformationnels,interactifs et réactifs[8]. Les  systèmes transformationnels  disposent de leurs  entrées dès leur initialisation et délivrent leur résultats lors de leur 

terminaison. l'exemple idéal de cette classe est un solveur d'équations dont la seule contrainte  est qu'il doit se finir en un temps fini.

Les systèmes interactifs réagissent continuellement avec leur environnement à leur propre  vitesse. On trouve dans cette classe les systèmes  d'interrogation de bases de données et les  systèmes d'exploitations, dont on réclame généralement avant tout la sûreté de 

fonctionnement.

La dernière famille de système,dit réactifs[8],réagissent continuellement à leur environnement  et à la vitesse imposée par celui­ci.

Les systèmes temps réels,les applications de traitement de signal et les applications vidéos à  haute performance ...etc , sont des bons exemples de tels systèmes.

De nombreux systèmes réactifs sont des systèmes embarqués,disposant de ressources réduites, il est donc également nécessaire de connaître les ressources nécessaires à l'exécution des  programmes. Pour satisfaire ces deux caractéristiques,les outils de description de systèmes  réactifs doivent garantir une exécution des programmes en temps et en mémoire bornée[8].

1.1 Déterminisme et concurrence

Les systèmes réactifs , de par leur nature et leur contexte d'utilisation,partagent deux  caractéristiques: déterminisme et concurrence.

Déterminisme

Les systèmes réactifs sont par nature déterministes : ils doivent réagir de la même 

manière aux mêmes sollicitations de l'environnement. cette caractéristique les différencie  des systèmes interactifs,qui sont souvent non­déterministes. De plus ,les activités de mise  au point,de certification et de test sont plus simples dans le cas de programmes 

déterministes. Cette caractéristique est ici particulièrement importante dans les systèmes  embarqués.

Concurrence

      Ces systèmes sont concurrents,le système travaille en parallèle avec son environnement et        interagit avec celui­ci .Il est plus souvent plus simple et plus naturel de pouvoir donner une        description parallèle d'un système permettant à la fois d'obtenir des définitions plus 

      simples et plus proches des spécifications des systèmes[8].

D'après ces définitions ,et puisque les systèmes embarqués  sont des systèmes réactifs,ils  vérifient la caractéristique de parallélisme(concurrence),c'est à dire que les programmes de  type « traitement de signal » par exemple sont des programmes parallèles.

(6)

Dans les paragraphes suivants nous présentons  quelques langages et modèles de 

programmations destinés à l'écriture de  ce type d' applications ,aussi les différents modèles de  communication.

 2.Modèle de programmation parallèle

Ce modèle doit abstraire le plus possible les traits liés à l'organisation d'un programme  parallèle, comme la décomposition ,l'ordonnancement,les communications et la  synchronisation.

La décomposition est la façon par laquelle un programme parallèle est divisé en  taches(modules) indépendantes. 

 

L'ordonnancement est lié à l'attribution de ces taches aux processeurs.

Ces deux items sont particulièrement importants pour obtenir l'efficacité optimale d'exécution  d'un programme parallèle.

La communication est une conséquence  des dépendances  de données entre deux taches ,et  nécessite la détermination des points adéquats où sera réalisé l'échange de données .

Enfin la synchronisation permet  de garantir que l'état global des taches reste cohérent c'est à  dire que les propriétés invariantes  d'état restent toujours vérifiées.

Une bonne  abstraction de ces traits aide à la compréhension et au développement  d'applications  parallèles.

évaluation

       L'emploi du parallélisme rend possible un accroissement des performances dans        différents domaines d'applications. Cependant l'expression de ce parallélisme        et l'exploitation des facilités mises à disposition par les architectures parallèles        restent toujours difficiles à l'heure actuelle. 

       Un programme parallèle reste complexe à élaborer car on doit coordonner les           différentes entités qui coopèrent pour l'obtention de la solution. Cette  

       coordination se présente sur différents niveaux :

       comment séparer un programme en taches indépendantes?

       comment déterminer quand et par qui une tache sera exécutée?

       comment échanger  des données entre les taches?

Pour essayer de répondre à ces questions la recherche en programmation parallèle  propose différents modèles et environnements de programmation et de    

 communication.

L'une des approches les plus intéressantes repose sur des modèles de programmation basés sur  l'interaction entre les processus et le réseau des processus .Ces modèles privilégient une  découpe du programme en processus et fournissent des mécanismes pour la communication .

(7)

Deux paradigmes de programmation largement répandus utilisent  cette approche : la programmation par échange de message et la programmation par mémoire partagée.

dans ce qui  va suivre nous présentons l'architecture de passage­message (standard MPI),et le  modèle de KPN(kahn process network).

II.Programmation par échange de message   et le Standard MPI

  

 1. Principe 

     Le parallélisme consiste essentiellement à diviser un problème donné en plusieurs sous            problèmes  et à les résoudre simultanément.         

     un programme parallèle est donc vu (dans ce modèle de programmation) comme un        ensemble de processus coopérants.

     Ces processus  peuvent être exécutés simultanément  sur différentes machines,        ou concurremment sur une seule machine. étant donné qu'il n ' y a aucune        restriction à propos du nombre de processus par processeur (machine parallèle       virtuelle).

     Les processus ne partagent pas de mémoire , la communication entre eux ne  se fait       que  par l'émission et la réception de message et au travers d'un canal .

    

   1.1 les primitives de communications:

      Deux opérateurs de base send(),et recv() permettent à une paire de processus        l'émetteur et le destinataire  d'échanger des messages entre eux .le nombre et la 

      complexité des paramètres de ces primitives varient selon la bibliothèque d'échange de        messages utilisée.

      send (message,type,quantité,,étiquette,dest);

      recv (message,type,quantité,,étiquette,source);

1.2 un canal :

Dans le plus simple des cas , il existe un canal unidirectionnel entre   toute paire de  processus. sur un canal , les messages sont acheminés dans l'ordre d'émission (un canal  FIFO) . Du point de vue de l'émetteur ou du récepteur, ce canal est simplement identifié  par le processus interlocuteur .C'est la solution qui s'oppose à celle identifiant 

explicitement le canal (e.g. socket dans les protocoles IP). Si deux processus utilisent  des flots de messages distincts , il faut pouvoir gérer plusieurs canaux logiques entre ces  processus .Ceci est fait simplement en étiquetant les  communications (tag) par le  numéro de canal logique à utiliser entre 2 processus[12].

       

(8)

2.Le standard MPI (message passing Interface):

       Le MPI  est un standard  issu des efforts de constructeurs de machines parallèles,           d'utilisateurs , de laboratoires de recherche et d'universités, afin  de définir la syntaxe et        la sémantique  d'un ensemble de routines destinées au développement de programmes       parallèles basés sur le paradigme d'échange de message.

      Il fournit des primitives pour le développement des programmes parallèles tels que:   

      les opérations d'accès à une mémoire distante ,les opérations de communication entre       processus et des opérations d'entrée/sortie(certaines primitives en particulier relatives        au temps réel sont fournies par la version MPI­2.0)[12].

    3. inconvénients de MPI

Les applications qui utilisent  cette bibliothèque sont non déterministes.

L'analyse et le débuguage des programmes utilisant cette bibliothèque sont très difficiles.

 Afin  de remédier à l'inconvénient de non­déterminisme  présent dans le standard MPI on  présente un autre modèle de communication , c'est  le KPN (Kahn Process Network).

III.KPN (Kahn Process Network)

Pour montrer le parallélisme et  la distribution de l'application ,nous avons 

présenté un autre modèle de réseau de processus , celui  proposé par Gille  Kahn (KPN).

ce modèle est souvent utilisé  pour modéliser les applications de traitement de signal . 1.Définition

Un KPN est un modèle de réseau des processus composé d'un ensemble fini de processus qui  communiquent entre eux par des canaux (file  de type FIFO) disposant d'une capacité de  stockage infini[3][6].

Chaque processus exécute un programme séquentiel pouvant utiliser des instructions de  lecture ou d'écriture sur un canal spécifié , de plus un KPN respecte la règle suivante:

un canal ne peut être connecté qu'à un seul processus en entrée  et  un seul processus en sortie  . Si le comportement des processus est déterministe, alors Gille Kahn a montré que 

l'histoire de chaque canal est également déterministe[3] .

(9)

2.Composants de base:

a) processus: Un KPN    est composé d'un ensemble de processus indépendants  qui sont         vérifiés , la propriété de déterminisme.

b) canal:  On trouve en KPN un ensemble de canaux  ,chaque canal présenté par une file          FIFO  de taille infinie.

c) Les opérations de lecture ou écriture (envoi ou  réception) sont  de type :

bloquant  pour la lecture (réception).

 non bloquant pour l'écriture (envoi) .

d) Chaque canal ne peut être connecté que par un producteur (un processus en entrée)  et un consommateur (un processus en sortie)[3][4] .

      

      

      produit       consommer après  la  production         

             

       figure1. la lecture et l'écriture dans un canal avec KPN 3. un  exemple:

processus three (int outport out)       processus four (int inport in){

       int j;

{       int k,t;

int i;       for (j=0 ; ; j++) for (i=0 ; ; i++) {      for (k=0; k<3;k++) w1: send (out,1);      R:  t[k]= receive (in);

}

}      int channel  c;

       four (c);

      three (c);

Description d'exemple:

La boucle infinie  signifie que la taille de canal est infinie.

L'opération de send permet d'écrire dans un canal.

L'opération de receive permet de lire une donnée dans une case de canal.

Dans la fonction principale l'interface entre un processus et un canal est réalisé au moment de lancement des processus.

|  |  |   |  |   |   |   |  |  |  |  |  |  |  |   |   |   |   |   |   |   |   |      

(10)

4. L'intérêt de KPN

­ L'un des intérêts des KPN en synthèse de systèmes embarqués est qu'ils permettent de  décrire des systèmes réactifs comportant du parallélisme, tout en se prêtant à une analyse 

« par dépendances » analogue à celle qui permet de traiter les codes séquentiels.

­ Un autre  intérêt est  le comportement  déterministe de canal, c'est le meilleur modèle  après les programmes séquentiels déterministes[3].

­ D'autre part , ils conduisent  à une représentation graphique qui est familière aux  spécialistes du traitement du signal et d'électronique.

­ Plusieurs applications de traitement de signal ,spécification VLSI  utilisent le KPN      comme un modèle de communication.

 5.Les limites et inconvénients de KPN

­   Le modèle de programmation KPN est asynchrone,par contre la plus part des systèmes      embarqués ont un modèle d'exécution synchrone,parce que les systèmes synchrones      sont faciles à spécifier ,implémenter et vérifier ,on peut aussi et facilement satisfaire      les contraintes de temps réel avec les systèmes synchrones.

L'un des problèmes les plus intéressants qui se pose au sujet de  KPN est la bornitude  des canaux ,qui conditionne évidemment la faisabilité  du système . 

Un autre aspect est celui de degré de parallélisme ,qui pour un KPN , est de l'ordre  du nombre de processus ( un KPN ,il n'accepte qu'un producteur et un consommateur  dans un canal donné) , il peut être  rare que ce degré puisse correspondre du premier  coup au matériel utilisé pour l'implémentation. il peut être aussi bien trop élevé que  trop faible,il n'existe  donc pas de paradoxe pour parler de parallélisation d'un KPN.

Une autre limite qu'on peut  présenter en KPN, c'est ce qui concerne la contrainte de  compte des messages. pour la construction d'une dépendance de message , on a besoin de compte des messages, c'est à dire on calcule le nombre des opérations 

d'envoi/réception, sur  un canal donné[4].

Note: Après la présentation de quelques concepts généraux qui sont liés à l'environnement de  travail  tels que le système réactif,système en temps réel,et quelques modèles de 

communication comme le standard MPI, et le modèle de KPN, on passe maintenant à la  présentation de la conception et l'implémentation de l' approche (CRP communicating Regular  Process), qui est au coeur de notre travail dans ce stage. 

(11)

IV. Conception

1.Conception de CRP (Communicating Regular Process)

1.1.Introduction:

Dans ce stage nous étudions un problème fondamental issu de l'expérience industrielle et  académique: la conception de système de traitement de flux vidéo à haute 

performance.

 Les langages de programmations de ce type d'applications sont basés sur le modèle de  communication de processus (réseau de processus) ,et différents  projets sont destinés a  l'écriture de ce type d'applications (e,g projet de SANDRA , Philips Eindhoven) qui écrit une  implémentation à base de réseau de Kahn (KPN) .

Malheureusement le modèle de  KPN a l'inconvénient d'être asynchrone  et présente aussi le  problème de comptage des messages (comme nous les avons  précédemment présenté).

Afin de remédier à ces problèmes , et Dans le cadre de projet de SYNTOL ,

Paul Feautrier   propose  une  approche[1], destinée à l'écriture  des applications de  flux  vidéos, c'est le CRP (Communicating Regular Process) et le modèle de communication en  CRP .

 Un programme  CRP est utilisé  comme  une spécification initiale (figure 2), dans le projet de  syntol.

 

       figure2. l'emplacement de CRP dans le projet syntol

Le langage CRP est une extension de C  destinée à l'écriture des programmes  de type 

« traitement de signal » pour systèmes embarqués. Par rapport  au C standard , il comporte des  processus , des canaux et des ports[1] .

(12)

Un programme  CRP ne peut pas être compilé par le compilateur C standard et encore moins  exécuté. En particulier , les mots­clefs: process,inport,outport et channel ne sont pas reconnus  par le compilateur  C. Ceci est gênant car il est impossible de valider un programme CRP  avant de réaliser le circuit correspondant . 

Le travail principale du stage est de réaliser un outils logiciel permettant de transformer un  programme  CRP en un programme C++, avec la définition des mots clefs  (channel,process,  inport,outport)  utilisant des outils ayant le même fonctionnement.

Pour vérifier le bon fonctionnement de cet outil logiciel , on sera amené à enrichir la base  d 'exemple du projet Syntol , par exemple en important et en adaptant des benchmarks postés  sur le web  par des projets analogues (SPARK, STREAMIT).

Dans ce chapitre nous présentons la sémantique de langage CRP  et ces composants de base ,  puis nous présentons la conception de transformation d'un programme CRP  en un programme  C++.

1.2.Définition  

Le CRP est un langage de spécification [1][5] qui utilise un processus comme un module  (comme dans KPN),mais la sémantique de  canal est changée .Ici on représente un canal par  un tableau de dimension arbitraire, un seul processus a le droit d'écrire dans chaque canal , et  cette écriture doit se faire en assignation unique : chaque case du canal ne doit être modifiée  qu'une seule fois . par contre il  n'y a pas  de restriction sur les lectures. il n'y a donc pas  d'ordres spéciaux pour l'émission ou la réception d'un message  ( i,e une seule écriture et  plusieurs lecture).

      Figure 3: Communicating Regular Process (CRP)

(13)

1.3.Composants de base 1.3.1. Processus: 

un processus est un :

­ Programme séquentiel , qui s'exécute en parallèle avec d'autres processus.

­ Un programme  en CRP est composé de plusieurs processus.

­ Tous les processus d'une application démarrent ensemble au début de l'application .

­ Chaque processus a des variables locales indivisibles à d'autres processus (on ne peut     pas  changer le contenu d'une variable globale ) .

­ Un processus peut être activé plusieurs fois .

­ Les processus  communiquent entre eux seulement à travers des canaux.

­ Un seul processus a le droit d'écrire dans un canal ,et plusieurs processus de lecture    peuvent  accéder à une case en même temps [1][5].

1.3.2 .canal:

Un canal est  un moyen de communication entre les processus , considère  comme un  tableau de dimension infinie supportant une seule écriture / plusieurs lectures[1].

chaque cellule de  canal contient un bit  de contrôle qui indique  si cette cellule est pleine  ou vide .

L'opération de lecture ne produit aucune modification du contenu de cellule d'un canal.

       1.3.3. Ports

Un port est l'interface entre un processus et  un canal .un processus peut être activé  plusieurs fois ,par un ordre de lancement situé dans un processus de plus haut niveau. 

un processus accède à un canal à travers un port , qui peut être  d'entrée (inport) ou de sortie (outport) . la correspondance entre port et canal se fait au lancement du processus  .De cette façon, les diverses activations d'un même processus peuvent utiliser des canaux  différents[1].

1.3.4. la bornitude de  taille de canal

La définition de langage CRP dit que  la taille de canal est infinie , il est nécessaire dans  la plus part des systèmes embarqués  d'utiliser une boucle infinie .mais au niveau du  matériel il est impossible de satisfaire cette condition parce que la taille de la mémoire  est limitée.

La solution est d'analyser la durée de vie de chaque donnée dans une case de canal et  vider ou réinitialiser cette case après le dépassement de cette durée de vie ( après la  dernière utilisation  du contenu de cette case ),  et dans ce cas le compilateur de CRP  accepte la boucle infinie avec l'utilisation d'une file circulaire de type FIFO.

le seul problème qui peut être posé dans ce cas est quand l'application supporte beaucoup  de parallélisme , qui exige un espace de mémoire important et qui peut être infini.

 

 Pour présenter une vue générale  sur les programmes en CRP  on introduit   l'exemple suivant :

(14)

1.3.5.Un exemple commenté

Le programme    suit est composé de 2 processus  producer, et consumer et la fonction  principale  main.

process producer (outport int x []) {

int i;

for (i=0 ; ; i++ ) K:    x[i]=2*i;

}

void traitement (int);

process consumer (inport int y[]) {

int i;

int j;

for (i=0 ; ; i++ ) W:  j=y[i];

Z: traitement (2*j); 

}

process producer (outport sortie[]);

process consumer (inport entre[]);

void main () {

channel a[];

T1: consumer (a);

T2: consumer (a);

S:  producer (a);

}

Ces 2 processus sont enregistrés dans le même fichier. ceci n'est pas obligatoire. il est plus  fréquent d'attribuer un fichier distinct à chaque processus (notre simulation supporte  le  deuxième cas).

Le processus producer fabrique une  valeur par une règle arbitraire (instruction K) et la range  dans le tableau x. ce tableau est en fait le canal a, avec le processus consumer .Ce processus lit  chaque élément du canal  y (instruction W) ,et appeler a la fonction traitement.

Le processus consumer est lancé 2 fois avec des canaux différents comme il  écrit dans la  fonction main (instruction T1 et T2).

On peut considérer que l'instruction K est l'émission d'un message et que W est sa réception . Comme le processus consumer va avoir tendance à aller plus vite que  le  processus  producer  (il n'a qu'une instruction à exécuter par tour de boucle au lieu de 2). il faut assurer une 

synchronisation.

(15)

Dans tous les processus, chaque opération de lecture ou d'écriture  se trouve dans une boucle  infinie.

Dans la fonction principale les instructions T1,T2,S présente le lancement de tous les  processus  ensemble au démarrage .(voir le code de ce programme en C++  en V.5).

2.Conception  de transformation 

Nous avons montré précédemment qu'on ne peut pas compiler un programme CRP par  un compilateur de C standard a cause des mots clefs: inport outport, channel et 

process .alors pour compiler un programme CRP on a besoin d'un véritable  compilateur qui définit ces mots clefs .

Dans ce qui suit nous présentons la conception de transformation d'un programme  CRP en un programme c++  et  des outils qui permettent de  définir  ces mots clefs  tout   en gardant la même sémantique de chaque composant (channel , inport,outport ,  process) comme cela est  présenté dans (1).

Nous présentons  aussi notre conception qui fournit des outils de synchronisation pour  accéder aux  canaux , de telle sorte d'éviter qu'un processeur attende d'accéder à une  case vide.

   2.1. conception d'un processus

On transforme chaque processus en CRP en une fonction. 

Le lancement de processus correspond dans notre conception  a  un lancement d'un  thread qui exécute la fonction.  

   2.2. les  primitives de synchronisation 

Un canal est représenté par un tableau de dimension arbitraire,les canaux deviennent la  mémoire partagée entre les threads .

Dans notre implémentation nous fournissons des primitives qui sont  rassemblées sous  forme d'une bibliothèque (voir la partie d'implémentation).et qui garantissent la 

synchronisation entre ces threads , les deux primitives (consumer et producer)  vérifient cette synchronisation avec les contraintes relatives a la sémantique  d'un  programme CRP développées dans les points suivants:

­ Un thread de lecture ne peut accéder à une case vide (ne contient aucune donnée).

­ Si un thread de lecture et un autre d'écriture accèdent en concurrent à la même  case,on bloque le thread de lecture et on laisse le thread d'écriture passer (la figure 4).

(16)

­Un seule thread d'écriture peut accéder a une case , et plusieurs threads de lecture  peuvent accéder a la  même case,  comme c'est présenté dans la figure4.

La figure4 présente l'accès de plusieurs threads (soit en lecture ou en écriture)  dans un     canal.

      

      thread d'écriture

      lecture     lecture      thread de lecture bloquer

       lecture

      figure4:  la sémantique de lecture et d'écriture dans un canal en CRP

         2.3. un canal et sa taille 

         La taille de canal en CRP est non bornée, et dans notre conception nous utilisons un           tableau de taille arbitraire pour définir un canal, ( on définit la taille de canal dans une            variable globale ) . alors pour vérifier le condition  de non bornée , nous fournissons une           primitive qui permet de réinitialiser chaque case dans le canal après l'utilisation, la          procédure de réinitialisation suit les étapes suivantes:

Compte le nombre de processus qui lisent dans un canal donné .

Lancer un compteur  dès la première lecture .

Réinitialiser la case lorsque le compteur atteint le nombre de processus qui doivent  être lus dans ce canal.

       

        2.4. inport et outport

L'interface entre un canal et un processus est établie soit en entrée par inport  ou en  sortie par outport (voir la partie d'implémentation pour le détail).

         

|  |  |  |  |   |   |   |   |   |   |   |   |   |   |   |   |    |

(17)

V. Implémentation :

Dans les paragraphes précédents nous avons présenté , la conception  des nouveaux mots clefs  (channel,process,inport,outport) dans notre compilateur, qui permet de compiler un 

programme  CRP , et fournit des outils ayant le même fonctionnement,  afin de respecter la  sémantique et les contraintes d'un programme  CRP. nous avons présenté aussi les primitives  qui permettent  de garantir la synchronisation entre les threads.

Dans ce qui  va suivre nous présentons la partie d'implémentation de notre compilateur , et  les différentes approches qui nous avons implémentées dans ce sujet telles que la bibliothèque  qui fournit des primitives de synchronisation, la  structure de compilateur, et la structure de  canal en détail  .

1.Une vue générale sur la  transformation  d'un programme CRP en programme  C++.

Le travail principal  dans la partie  d'implémentation  que nous avons réalisée  consiste à  analyser un programme CRP (analyseur lexical et syntaxique), à l'aide de yacc et lex, et à convertir son contenu en un programme C++ . Ce contenu écrit dans un nouveau  fichier d'extension « .C »  ,une fois la conversion est terminée on compile ce nouveau  programme par un compilateur  de C standard et on ajoute notre bibliothèque qui fournit  des primitives de synchronisation , la figure 5 résume ce travail.

       fichier.h       compilateur    programme       de C standard   en CRP       programme       +

      en C++      bibliothèque           fichier exécutable

       

      figure 5: le déroulement de transformation d'un programme en CRP à l'aide de notre        compilateur et bibliothèque.

2. la structure de compilateur

La  figure 6  présente  la structure générale de compilateur qui réalise cette transformation. 

Le fichier cri.ml contient la représentation interne d'un programme CRP, les fichiers   clex.mll  et cstax.mly  correspondant aux analyseurs lexical et syntaxique.

Le fichier xpretty.ml contient le code qui permet de transformer chaque instruction  CRP en  instruction en C++ , y compris les mots clefs processus,channel,inport, outport.[2]

notre compilateur

(18)

       

      figure6: graphe de dépendance de compilateur

3.une vue générale  sur la  syntaxe  de transformation

On a déjà dit que la syntaxe d'un programme CRP est la même qu'un programme C, il reste de transformer les mots clefs inport,outport,channels et processus.

3.1 process :  Le mot process est définit comme un type de base .

  Le convertisseur de type process indique que c'est un type d'une fonction ,par exemple  process foo (paramètres,,,);

 alors le corps de la fonction foo  doit être lancé par un thread.

on transforme l'exemple précédent   comme  suivant: void  foo (paramètre);

3.2 channel : La déclaration de mot clef channel en CRP joue le même rôle  que : volatile  ou const .

L' exemple  suivant : channel  int c ;signifie que la variable c est un canal de type entier.

Le convertisseur transforme cette écriture comme suit:  canal< int > c ; c.Init(paramètres);

c'est à dire que c est un  canal de type entier, et la deuxième instruction permet d'initialiser  les paramètres de ce canal.

cri.ml

tools.ml

cstax.mly

clex.mll

xpretty.ml

cxml.ml

(19)

La classe canal contient:

   ­ Un tableau DATA de type template , la taille de ce tableau est constante      (TAILLE_CANAL) .

   ­  Chaque champ de tableau comporte aussi 3 bits:

un bit ecrit, et bit plein: de type sémaphore pour indiquer si la case  est vide ou plein.

un bit bit contient le nombre des processus qui doivent être lus dans  ce canal.

­  Définit aussi les primitives producer, consumer  qui permettent d'effectuer des 

   opérations de lecture et écriture dans un canal, tout en  garantissant la synchronisation.

­ Une primitive de réinitialisation de case dans un canal.

3.3 inport et outport

      La déclaration d'une variable de type inport ou outport comme dans l' exemple:

      inport float a; signifie que  la variable a est  l'interface vers un canal de type float.

      

      Le convertisseur transforme cette déclaration  comme suit:

      canal<float>*a; tel que a est un pointeur vers un canal de type float, et la même chose        pour  outport.

   3.4 la boucle infinie:

La syntaxe de la boucle infinie utilisée dans un programme CRP   écrit  comme dans  l'exemple suivant:

process source(outport float a[]){

    int i;

    for(i=0;;i++)  P:     a[i] = cos(i);

}  

  Le convertisseur transforme l'écriture de la boucle for  comme suit:

  for (i=0; i<TAILLE_CANAL;i=div(i+1,TAILLE_CANAL).rem) { ...}

tel que TAILLE_CANAL est constant .

L'instruction  i=div(i+1,TAILLE_CANAL).rem; permet de toujours vérifier la condition 

« i>TAILLE_CANAL » (i,e le compteur est toujours inférieur à la taille de canal).

3.5. Lancement d'un processus

L'instruction de lancement de processus dans le programme CRP  est présentée par un appel a  ce processus, comme c'est présenté dans l'exemple suivant:

process foo (inport float a);

void main () {channel k;

W: foo(k);}

(20)

Le convertisseur transforme l'instruction w à l'instruction ww : ww: lance_process (foo, param..);

tel que la fonction lance_process défini dans  notre bibliothèque   lance la fonction foo par un  thread.

3.6.l'opération de lecture /écriture (envoie et réception)

Les opérations de lecture et écriture dans un programme  CRP ,sont transformées par le  convertisseur comme suit:

la lecture/écriture dans un canal 

Un programme  CRP écrit une opération de lecture dans un canal : process foo (inport float a,outport b)

{ int k;

for (i=0;; i++)      {w: k=k+a[i];

       z: b[i]=k;}}

       

Le convertisseur transforme l'instruction w à un autre code qui est:

      w1:     a­>consumer (i);

       w2:     k=k+a­>DATA[i];

tel que:

Dans l'instruction w1, la fonction a­>consumer ()  permet de vérifier si la case est         vide ou non.

Dans l'instruction w2 ,a­>DATA[i] permet d'accéder a la case i du canal a.

 Pour l'instruction z ,transformer par:  b­>producer(i,k);

4.contraintes :

        Un programme  CRP doit  utiliser  les mots clefs channel,process,inport,et                outport  dans le sens suivant:

 channel,inport et outport doivent être utilisés seulement pour la  déclaration des  scalaires. on ne peut pas déclarer un tableau des canaux ou  un pointeur vers un port  par exemple.

process peut être utilisé seulement pour des fonctions de qualifications, on ne peut  pas par exemple  avoir un tableau des processus.[1].

(21)

Dans le cas où un programme CRP contient une instruction qui ne respecte pas 

cette sémantique , alors  la transformation correspondante engendre un code incohérent(des  erreurs).

Un autre point qui est très important dans  notre conception , qui est  la réinitialisation des  cases d'un canal donné.

Le convertisseur  ajoute une instruction a la fin de chaque  processus, a condition que celui ci  comporte une instruction de lecture dans un canal . La syntaxe de cette instruction est  écrite  comme suit:

(*nom de canal*).Rinit(compteur de boucle infini);  

     telle que: la fonction Rinit permet de réinitialiser la case définie par la valeur de         compteur de boucle infinie.

5.Exemple de transformation:

Le code C++  du programme CRP  (présente dans la partie de conception (1.3.5))  écrit par  notre compilateur comme suit:

le code correspondant au processus producer void* producer ( void* CANAL ) {

int  i ; 

 t_producer* p_producer;

 p_producer=( t_producer* )  CANAL ;

 for (   i= 0 ; i< TAILLE_CANAL; i = div(  i +1, TAILLE_CANAL ).rem  ) {   p_producer­>x­>dproducer ( div( i,TAILLE_CANAL).rem, pthread_self() ); /*1*/

p_producer­>x­>DATA[div ( i,TAILLE_CANAL).rem]= 2*i; /*2*/

p_producer­>x­>fproducer ( div( i,TAILLE_CANAL).rem ) ; /*3*/

sleep (2);

 } }

le code correspond au processus consumer void  traitement (int  a) ; 

void* consumer ( void* CANAL ) {  int  i ; 

int  j ; 

 t_consumer* p_consumer;

 p_consumer=( t_consumer* )  CANAL ;

 for (   i= 0 ; i< TAILLE_CANAL; i = div(  i +1, TAILLE_CANAL ).rem  ) {  

    p_consumer­>y­>consumer ( div(  i,TAILLE_CANAL).rem, pthread_self() ); /*4*/

    j=p_consumer­>y­>DATA [div( i,TAILLE_CANAL).rem] ;  /*5*/

 

traitement(j) ; 

p_consumer­>y­>Rinit (i);

sleep (2);

 }}

(22)

le code correspond au processus principale (main)    extern void* producer ( void* ) ;

  extern void* consumer ( void* ) ;    int  main () {

  chanal <int  > a ;   a.Init (nbr_a) ;   void * v_nour ;

  printf ("\n lancement de tous les processus") ;     t_consumer p_consumer_T1;

p_consumer_T1.y =  &a;

pthread_t *th_consumer_T1;

v_nour = (void*) &p_consumer_T1;

th_consumer_T1 = Lance_Process ( consumer , v_nour )  ;    

t_consumer p_consumer_T2;

p_consumer_T2.y =  &a;

pthread_t *th_consumer_T2;

v_nour = (void*) &p_consumer_T2;

th_consumer_T2 = Lance_Process ( consumer , v_nour )  ;   t_producer p_producer_S;

p_producer_S.x =  &a;

pthread_t *th_producer_S;

v_nour = (void*) &p_producer_S;

th_producer_S = Lance_Process ( producer , v_nour )  ;   Att_process ( th_producer_S) ;

Att_process ( th_consumer_T2) ; Att_process ( th_consumer_T1) ; return 0 ;

 }

le contenue de ficier defin_struct.h

#ifndef DEFIN_STRUCT_H

#define DEFIN_STRUCT_H

#include <stdio.h>

#include <string.h>

#include "Declaration.h"

#include "chanal.c"

#define nbr_a      2

 typedef struct s_producer{

 chanal <int  >* x ;  }t_producer ;

 typedef struct s_consumer{

 chanal <int  >* y ;

(23)

 }t_consumer ;

#endif

Description du code 

Dans ce code les instructions les plus intéressant sont:

        ­ La déclaration et l'initialisation de canal:

L'instruction canal <int>a  dans la fonction principale ,permet de définir une classe    a  (template) de type int , qui est le canal a, et l'instruction   a.Init (nbr_a) ;

permet d'initialiser les différents paramètres de canal a tel que:

nbr_a présente le nombre des threads qui seront lisent dans le canal a.

La valeur de nbr_a est défini dans un fichier « defin_struct.h ». 

Le fichier defin_struct.h rassemble les variables globales et les différents structures    utilisées dans l'application. 

      ­l'écriture dan un canal:Dans la fonction  producer ,l'instruction d'écriture est          présenté par les 3 instructions : les instructions 1et 3 (/*1*/ et /*3*/) , permettant de        protéger l'accée à la case i de canal  par d'autre threads de  lecture, et l'instruction         /*2*/ écrit une donnée dans cette case.

      ­ la lecture de donnée dans un canal:Dans la fonction   consumer, l'instruction

         de lecture dans une case de canal est présenté par les 2 instructions 4 et 5 (/*4*//*5*/),              l'instruction 4 permet de vérifier si la case est vide ou plein ,(s'il est vide la primitive          consumer est bloqué par un variable de type sémaphore), et l'instruction 5 lise la           donnée (si la case est plein).

     ­Lancement de processus   : Comme il présente dans l'instruction principale,         l'appel à l'instruction Lance_process (producer,v_nour), permet de lancer la            fonction producer par un thread et passer la structure v_nour comme paramètre          a ce thread.

    ­la structure (t_consumer et t_producer): Les processus ce sont des fonctions lancées par          des threads, alors comme il présente dans (fonction producer et consumer),on donne le         type void au résultat retourner par  ces fonctions ,avec le paramètre CANAL de type void         aussi, la structure t_producer dans (producer) comporte comme des champs ,les

        paramètres qui sont défini dans le processus (producer.crp),tel que  t_producer définit         comme suit:

typedef struct s_producer{

      chanal <int  >* x ;        }t_producer ;

    ­ La rinitialisation d'une case de canal: Dans la fonction de producer,        l'instruction p_consumer­>y­>Rinit (i); permet de réinitialiser la case i        après la l'écriture de donnée sur cette case.

   ­ l'instruction Att_process ( th_consumer_T1) : Cette instruction permet d'attendre le  thread qui exécute la fonction consumer jusque la fin de son exécution.

(24)

XI.APPLICATIONS

Pour vérifier le bon fonctionnement de notre outil logiciel ,on sera amené à enrichir la base  d'exemple du projet SYNTOL,par exemple en important et en adaptant des benchmarks postés  sur le web par des projets analogues . dans notre travail nous choisissons une application de  codage des flux vidéo avec la norme MPEG.

 le code de cette application est disponible en StreamIt (réalisé par le projet de  StreamIt)[10][11].

D'abord on présente le principe de cette norme pour le codage des flux vidéos,

puis on présente le schéma correspondant (le graphe de communication des processus ) dans  cette application ,ensuite on écrit le code correspondant en CRP,pour en fin compiler ce code  par notre compilateur.

1.La norme MPEG

La norme MPEG  a été le premier des travaux sur la vidéo et a permis la compression  efficace de  ce type des données. Cette norme décrit une syntaxe hiérarchique en  décomposant une séquence vidéo en plusieurs parties qui ont toutes un rôle dans le  codage et la compression de cette séquence.

Le codage et le stockage du MPEG repose sur des outils que nous allons décrire maintenant.

2.structure  d'une séquence vidéo MPEG

La figure7 présente la décomposition d'une séquence vidéo avec la norme MPEG

      figure7 : la structure d'un séquence vidéo avec  la norme MPEG

(25)

Une séquence vidéo est décomposée en groupe d'images, et chaque groupe comporte 

un certain nombre d'images, et chaque image a son tour est décomposée en d'autres  types de  format.

Comme c'est illustré  dans la figure7 ,le Bloc  est le dernier composant utile de cette structure  hiérarchique.

Les blocs sont des carrés de 8*8 pixel, afin de simplifier les choses on présente chaque bloc  par une matrice de dimension (8,8).

On présente par un schéma  les différents processus et la communication entre eux, afin de  coder et stocker un bloc.

     

      figure8: schéma de codage/stockage d'un bloc  d'image avec MPEG

3. Description  de schéma de codage/stockage d'un bloc d'image avec MPEG Le schéma présente par la figure8 constitué un graphe  tel que :

les rectangles sont des processus.

les flèches sont des canaux de communication entre les processus.

        a) Description des processus : 

      Le schéma  présente  5 processus (splitter,zegzag,IDCT,repeat et add).

VLD:  Ce processus produit en sortie  une matrice  de dimension (8,8) qui  présente le  bloc, et un vecteur  contient des informations concernant le format de  l'image. 

zegzag:  L'entrée de zegzag est  la matrice produite par VLD . ce processus  traite  les éléments de cette matrice, et produit en sortie un tableau de dimension 8*8 (64  éléments).

IDCT :  L'entrée de ce processus est le tableau produit par le processus zegzag,  fait un traitement (transformation inverse de descret cosinus), et produit un tableau  de même dimension  dans la sortie.

repeat:  L'entrée de ce processus est le vecteur produit par  VLD. La        sortie est une valeur de type entier .

add : L'entrée de add est la valeur produite par le processus repeat, et le          tableau de dimension (64)  produit par le processus IDCT.  

      Un traitement est fait sur ces éléments, et appele à une fonction.

VLD

repeat

zegzag IDCT

add

(26)

note: Ce schéma est une simplification de  codage et stockage (certains processus concernant  le codage sont supprimés), et non pas un schéma complet de l'application.

L''écriture de l'application de codage  en CRP permet d'ajouter  à celle ci la propriété de  parallélisme  , afin d'accélérer l'opération de codage.

Dans le schéma de figure 8 , on remarque que les processus IDCT et zegzag peuvent    faire  des calculs parallèlement  avec  le processus repeat.

Le code source de cette application en CRP et en C++ est présenté dans la partie Annexe.

VII.Efficacité et Discussion

Le langage CRP  présenté en détail dans ce rapport , et la sémantique qui lui est associée,  concernant la structure de canal,les processus ou le mode de lecture et écriture des processus  dans les canaux , ont pour but de rendre les applications de traitement de signal , en particulier  de flux vidéo, plus fiables et efficaces ,et ceci de différentes manières :

   1.la degré de parallélisme  :

     Le langage CRP permet d' augmenter la degré de parallélisme de ce type d'applications         soit au niveau de compilation ou au niveau d'exécution:

au niveau de compilation :  Considérer chaque processus  comme un module  indépendant , par conséquent ,éviter de recompiler toute  l'application en cas  d'erreur localle (gain de temps de compilation)[1][5].

au niveau d'exécution: En CRP tous les processus démarrent ensemble au début  de l'application,et sont exécutés en parallèle , avec une garantie de 

synchronisation d'accéder dans les canaux (la partie essentielle de notre travail).

      Cette propriété conduit aussi a un gain de temps ,par conséquent supporter plus        en plus des applications pour systèmes embarqués et en temps réel.

Le mode de lecture et écriture  supporté en CRP (une écriture et plusieurs lectures),permet  aussi d'augmenter la degré de parallélisme,( contrairement au KPN par exemple qui supporte  seulement une seule écriture et une seule lecture) , parce que la propriété de plusieurs lectures  permet  a plusieurs processus de lire la même donnée (qui écrit une fois).

Ce mode de lecture/écriture permet aussi d'écrire de nouvelles applications de flux vidéo   qui  ne peuvent  être  supportes par d'autres langages qui  exigent d'autres sémantiques . l'une de ces applications ,par exemple , celle qui consiste à faire plusieurs copies de même  image ,dans ce cas on peut lancer le même processus de copiage plusieurs fois, avec des  paramètres différents .

(27)

 Une autre application qui consiste à faire une copie d'une image et de changer l'échelle  comme c'est présenté dans la figure suivante :

          

   

      figure9:schéma de copiage et changement de  l'échelle d'une image

  2.La syntaxe de langage : Le langage CRP a la même syntaxe du langage C (comme             présenté précédemment), cela permet d'utiliser différentes primitives fournies par le           langage C et surtout des primitives de manipulation sur les signaux (tel  que sigalarm..) .           par conséquent il permet d'écrire  d'autres applications de traitement de signal.

 3.Consommation de mémoire : En CRP on utilise des canaux de taille bornée, et à l'aide         de réinitialisation des cases de canal , on peut  diminuer la consommation de mémoire,         mais cette solution pose un autre  problème qui sera présenté par la suite.

 Le langage CRP  rend un certain nombre d'applications de traitement de signal plus  fiables,mais il reste  d'autres problèmes qui n'ont pas été encore résolus ,ou  des nouveaux  problèmes sont  rencontrés avec  d'autres applications , nous citrons,dans ce qui va suivre,  quelques problèmes ,dont certains sont en cours d'études:

La taille de canal et la réinitialisation des cases: 

Le problème majeur présenté dans CRP est le choix de la taille de canal.

dans notre simulation nous avons fixé la taille de canal par une constante  , la valeur de  cette constante est choisie aléatoirement  sans  aucune méthode ou algorithme ou tout  autre critère .

       Le problème  principal  dans le choix de  cette valeur  est que , d'un coté,  

       l'environnement de travail (système embarqué) exige une utilisation très limite de la           mémoire, et d'un autre coté , certains type d'applications supportent  l'utilisation de la         mémoire pour augmenter la degré de parallélisme .

       Pour résoudre le problème de taille de canal, on doit chercher à trouver une solution,qui         permet de réutiliser le même espace mémoire de canal,parce que il faut limiter la taille         de canal (a cause de limite  matérielle).

       paul en [1], présent  une méthode ,qui  consiste à  réinitialiser une case de           canal après chaque utilisation afin de réutiliser cet espace . Cette réinitialisation         dépend d'un critère de durée de vie de donnée .

source | | | | | | 

copier

changer l'échelle

(28)

       durée  de vie de  donnée: C' est le temps entre l'écriture de donnée dans la case et sa           dernière utilisation par des processus[1][5].

       par conséquent la réinitialisation des cases de canal permet  de réutiliser ces cases         plusieurs fois.

       Cette solution pose un autre problème , c'est comment calculer la durée de vie de         donnée?

      En  StreamIt par exemple ,la méthode INIT, dans la classe filtre , permet de positionner       le  nombre des données produites et consommées  dans le canal au démarrage .

      Dans notre simulation l'opération de réinitialisation  des cases d'un canal est basée sur le         nombre  des processus qui lisent dans ce canal, ce nombre est calculé au  début de          lancement des processus.

Un autre problème  peut être  posé dans le même sujet , c'est quand la durée de vie d'une  donnée dans une case est  longue (le temps de garder une donnée dans une case est prolongé). 

Ce cas peut être présenté avec des applications qui supportent beaucoup de parallélisme, en  particulier, quand on a plusieurs  processus de lecture  dans un canal,alors il faut garder le  contenu de chaque case, jusqu'à  la dernière lecture,qui conduit à un cas où le processus  qui  écrit dans le canal se bloque parce que il n'y a aucune case vide pour écrire des données,   et  l'opération de réinitialisation  attend le délai pour vider une case (voir la figure10).

             

        lecture       écriture       lecture       lecture         lecture               après n cycle 

       d'exécution

lecture       écriture bloquer

      lecture       (attente l'opération de lecture)        

       figure10: le problème de ré initialisation de cases

Une solution peut être présenté pour ce problème qui consiste à  limiter le nombre de 

processus de lecture dans un canal donné, mais cette solution permet de diminuer la degré de  parallélisme.

problème techniques:  L'un des problèmes techniques que nous n'avons pas résolus  est le choix de l'ordre de l'instruction de réinitialisation dans le code d'un  processus . dans notre simulation on lance l'opération de réinitialisation à la fin de processus.

D'autres limites qui peuvent être présentés aussi en CRP :

certaines applications ne supportent pas la sémantique de CRP[1] .

le projet de  SYNTOL  est en cours de développement.

plusieurs recherches et études concernent le calcul d'ordonnancement en  CRP[5].

|  |  |   |   |   |   |   |   |   |   | |  |  |   |   |   |   |   |   |   |   |

(29)

IIX.CONCLUSION

Ce stage montre que plusieurs applications de traitement de signal , en particulier de flux  vidéo sont possibles à écrire avec le langage CRP qui est le coeur de nos études, parce que ce  langage fournit une sémantique et un modèle de communication , qui ne peuvent pas être  trouvés  avec d'autre langages qui utilisent par exemple le modèle de communication KPN.

L'écriture des applications en CRP permet de vérifier de plus en plus les contraintes de  l'environnement de travail (systèmes embarqués).

 La sémantique de CRP permet d'augmenter la degré de parallélisme,par conséquent un gain  de temps (un temps réel)  exigé pour les  systèmes embarqués .il permet aussi de diminuer la  consommation de mémoire .pour satisfaire  cette condition   une sémantique et des approches  destinées à cet égard et  qui consistent  par exemple  à  réutiliser le même espace mémoire  plusieurs fois. plusieurs recherche  et travaux,concernant ce point, sont en cours .le but  c'est  d'améliorer  ou  de trouver d'autres méthodes plus efficaces . 

D'une autre part, le travail que nous avons réalisé durant ce stage : 

le compilateur qui permet de compiler une application écrite en CRP, et produire un  code correspondant  dans un langage  de plus haut niveau (langage C++). 

la bibliothèque qui elle fournit des primitives  garantissant  une synchronisation entre  les processus de l' application pour accéder  à un espace mémoire partagé entre eux  (un canal).

Ce travail permet de supporter de plus en plus d'autres applications de traitement de signal. 

par conséquent enrichir la base d'exemples de projet de syntol qui est en cours de  développement par l'équipe compsys .

En ce qui concerne l'expérience réalisée pendant le stage, il faut noter l'importance du travail  dans un environnement de systèmes embarqués ,et avec des applications qui supportent des  modèles de communication comme celui   présenté en CRP.

D'autres expériences notées  concernant des principes et des outils de compilation tel que le  langage ocaml et le c++.

(30)

Annexe:

le code en CRP et en C++ réalisé par notre compilateur de l'application de MPEG qui est  présenté dans ce rapport, est ecrit comme suit:

1.le code en CRP:

le fichier vld.crp struct  MBloc       { float Block [8][8];};

struct FBlock       { int format [3];};

process vld (outport struct MBloc bloc[],outport struct FBlock vect[]) {

struct MBloc TMBlock;

struct FBlock TFblock;

int i,j,k;

float s;

for (i=0;;i++)   {

   for (j=0;j<8;j++)        for (k=0;k<8;k++)         

        TMBlock.Block[j][k]=2*j+k;

   bloc[i]=TMBlock; 

   for (j=0;j<3;j++)

       TFblock.format[j]=2*j;         

   vect[i]=TFblock;     

       } }

le fichier zegzag.crp struct TBlock 

{

float tableau [64];

};

struct  MBloc

      { float Block [8][8];};

(31)

process zegzag (inport struct MBloc  block[],outport struct TBlock tab[]) {

struct TBlock temp;

int i,j,k;

 for (i=0;;i++)  {

   for (j=0;j<8;j++)        for (k=0;k<8;k++)

       temp.tableau[8*j+k]= block[i].Block[j][k];

      tab[i]=temp;

 } }

le fichier idct.crp float coef[8][8];

struct TBlock  {

float tableau [64];

};

process idct (inport struct TBlock entre[],outport struct TBlock sortie[]) {

struct TBlock temp;

int i,j,k;

for (j=0;j<8;j++)     for (k=0;k<8;k++)         coef[j][k]= j*k;

for (i=0;;i++) {

    for (j=0;j<8;j++)         for (k=0;k<8;k++)

      temp.tableau[8*j+k]=coef[j][k]*entre[i].tableau[8*j+k]; 

        sortie[i]=temp;   

} }

(32)

le fichier repeat.crp struct FBlock 

     { int format [3];};

process repeat (inport struct FBlock form[],outport int typ[]) {

int temp;

int i,j;

for (i=0;;i++)     {

     for (j=0;j<3;j++)

         temp=temp+form[i].format[j];

     typ[i]=temp;

    }}

le fichier jointer.crp struct TBlock 

{

float tableau [64];

};

extern void stocker (int a,float aa[64]);

process jointer (inport int entre1[],inport struct TBlock entre2[]  ) {

int i,j;

float temp[64];

for (i=0;;i++) {

 for (j=0;j<64;j++)

     temp[j]= entre2[i].tableau[j];

stocker (entre1[i],temp);

}}

le fichier mpeg.crp struct FBlock 

     { int format [3];};

struct  MBloc

      { float Block [8][8];};

struct TBlock  {

(33)

float tableau [64];

};

process vld (outport struct MBloc bloc[],outport struct FBlock vect[]);

process zegzag (inport struct MBloc  block[],outport struct TBlock tab[]);

process idct (inport struct TBlock entre[],outport struct TBlock sortie[]);

process repeat (inport struct FBlock form[],outport int typ[]);

process jointer(inport int tt[],inport struct TBlock aa[]);

void main () {

channel struct MBloc block[];

channel struct FBlock vecteur[];

channel struct TBlock tabl1[];

channel struct TBlock tabl2[];

channel int c[];  

V:vld(block,vecteur);

W: zegzag (block,tabl1);

X:idct(tabl1,tabl2);

Y:repeat (vecteur,c);

Z:jointer (c,tabl2);

}

le fichier stocker.crp (fonction )

void stocker (int a, float b[64]) {

int s;

int i;

float c [65];

for (i=0;i<64;i++)     c[i]=b[i];

c[64]=a;

}

Références

Documents relatifs

● Initiée en 2019 par les membres du volet Formation de l’équipe projet I-SITE FUTURE* (projet institutionnel et scientifique financé par l’Agence Nationale de la Recherche qui

Our proposed patterns can be directly used in a modeling session and support the modeling of flexible process parts.. While discussing the process, domain experts explain

Pour y faire une concertation élargie sera recherchée (Centre Régional d’Investissement, Agence Urbaine pour le Développement, société civile, etc.).. La méthodologie

soit vous créez de A à Z votre propre donne, soit vous modifiez une donne, soit vous avez une donne déjà enregistrée (il vous faudra la charger dans l'éditeur en vue de

Des cellules qui n’ont jamais été exposées aux UV, sont prélevées chez un individu sain et chez un individu atteint de Xeroderma pigmentosum.. Ces cellules sont mises en

Les tâches possédant une date au plus tôt égale à leur date au plus tard font partie du chemin critique, c'est-à-dire le chemin sur lequel aucune tâche ne doit avoir de retard pour

Key words: Central limit theorem, {3-mixing processes, Donsker invariance principle, strictly stationary sequences, empirical processes, entropy with

Ce cadre terminologique constitue un bon support pour formuler les objectifs généraux d'un projet pédagogique d'une équipe.. La formulation