Occam (langage)

Le langage de programmation Occam est un langage de programmation adapté à l'architecture parallèle, apparu en 1983. Il a été développé par Inmos pour la programmation de ses architectures en parallèle Transputer, mais a également été porté sur d'autres plates-formes.

Ne doit pas être confondu avec OCaml.

occam
Date de première version 1983
Paradigme Programmation concurrente, calcul distribué, Impératif
Développeur Inmos
Dernière version 2.1 (1988)
Influencé par Processus séquentiels communicants

Le nom est un hommage à Guillaume d'Occam (parfois orthographié Ockham) et au principe méthodologique du rasoir d'Occam.

Le langage Occam est un langage procédural qui offre, outre l'exécution d'instructions séquentiellement (avec SEQ), l'exécution des instructions en parallèle (avec PAR) et même la mise en « parallèle asynchrone » de processus (avec ALT) pour une exécution non-déterministe d'un parmi plusieurs. L'exécution en PAR des processus se fait avec des rendez-vous, comme en Ada.

Occam contient aussi les « commandes gardées » de Edsger Dijkstra : un processus n'est lancé que si la valeur de sa garde, évaluée par le système, est vraie.

Le Transputer Development System (TDS) d'Inmos était l'outil de développement classique pour ce langage, mais il était possible d'utiliser Parallel C ou d'autres outils. L'éditeur du TDS permettait le pliage de code[1], ce qui était très innovant[2].

Principes de base

En Occam l'indentation est significative, ce qui évite les marqueurs de début et de fin de blocs communs à d'autres langages héritant de Pascal et C (begin...end, {...}, loop...endloop etc.). Une expression est terminée par une fin de ligne. Plusieurs expressions peuvent être regroupées dans un bloc dont toutes les lignes commencent à la même indentation.

La communication entre processus parallèles se fait avec des "canaux" définis par l'expression "CHAN OF". Ces canaux sont implémentés par les liens bidirectionnels série rapides (2 Mb/s, 4 liens/Transputer, communication indépendante du CPU). Un processus envoie des données sur le canal avec "!" tandis qu'un autre processus reçoit les données avec "?", l'émission et la réception étant synchrones  :

 keyboard ? c
 screen ! c

SEQ introduit une liste d'expressions qui sont évaluées en séquence, l'une après l'autre. Exemple:

 SEQ
   x := x + 1
   y := x * x

PAR annonce une liste d'expressions qui sont susceptibles d'être évaluées simultanément. Exemple:

 PAR
   p()
   q()

ALT indique une liste d'instructions gardées. Les gardes sont des combinaisons de conditions binaires et d'entrées sur canal. Une alternative parmi celles dont les conditions sont vraies et dont les canaux en entrée sont prêts, est exécutée. Exemple:

 ALT
   count1 < 100 & c1 ? data
     SEQ
       count1 := count1 + 1
       merged ! data
   count2 < 100 & c2 ? data
     SEQ
       count2 := count2 + 1
       merged ! data
   status ? request
     SEQ
       out ! count1
       out ! count2

Cet exemple va lire les données des canaux "c1" et "c2" (s'ils sont prêts) et les fusionner dans un unique canal "merged" de sortie . Si le compteur countN atteint 100, la lecture du canal N sera désactivée. Une requête sur l'état du canal aura pour réponse les deux compteurs.

Exemples de code

Quelques exemples de code réel

PROC Passe1 ( CHAN OF ANY FromKeyboard, CHAN OF INT FromServer, CHAN OF ANY ToServer, CHAN OF ANY FromNetwork, ToNetwork,
              []CHAN OF Process FromMenu, CHAN OF FilerProtocol FromFiler, ToFiler, []INT UserWindow, SystemWindow,
              []INT ConfigData, freespace, VAL []BYTE parnomfic, parNumVersion, FicSorties, INT FicSortiesPtr )
-- Constantes de configuration disque
VAL WrkExt IS ".CPS":
VAL OutExt IS ".LIE":
VAL IntExt IS ".$$$":

VAL MaxCompressedRecordSize IS 45: -- taille avec compression CGA !!!
VAL kAccesSequentiel IS TRUE:
VAL theta1 IS 1.618 (REAL32):
-- Constantes estimees
VAL MaxTailleZone IS 9111833:
VAL MaxVilles2 IS INT ROUND ((REAL32 TRUNC MaxVilles)*theta1):
-- Variables
[ReadBufferSize]BYTE MyReadBuffer: 
INT FicPos, FicSize:     -- position dans, et nombre d'octets du, fichier
[80]BYTE FicRes1,
         FicInt:

-- Fonctions
BOOL FUNCTION EndOfFile() IS ( (FicPos+MyReadPtr) >= FicSize ) :
BOOL FUNCTION NotFini() IS ( (Result=0) AND (NOT EndOfFile()) ) :

PROC Erreur ( VAL []BYTE par )
  [82]BYTE loc:
  --BOOL poub:
  --INT len:
  SEQ
    --len:=82
    --InitTabByte(loc,' ')
    [loc FROM 0 FOR (SIZE par)]:=par
    [loc FROM (SIZE par) FOR 2]:="*c*n"
    --delete.string(len,loc,(SIZE par)  +  2,81  -  (SIZE par),poub)
    WriteInTextWindow(ToServer,SystemWindow,[loc FROM 0 FOR (SIZE par)  +  2]))
    --              previously UserWindow

Autre exemple :

IF
  sgf.res <> 0
    SKIP
  TRUE
    IF
      compare.strings (ThfareKey, "99999999") <> 0
        SEQ
          ThfareKeyInt := AtoI (ThfareKey)
          ThfareOffsets [ThfareKeyInt] := Offset
      TRUE
        SKIP

Exemple de multiplexeur de canaux :

WHILE TRUE 
  VAR x;
  SEQ
    ALT
      c1 ? x
      c2 ? x
      c3 ? x

Évolution

  • occam 1 (1983) fut une version préliminaire, inspiré du travail de David May sur EPL, et de celui de Tony Hoare sur CSP. Cette version n'admettait qu'un type de donnée, noté VAR, désignant un entier ayant pour longueur le mot de la machine-cible, et des tables à une dimension.
  • occam 2 (1987) en est une extension opérationnelle produite par INMOS Ltd ; elle ajoute la virgule flottante,les fonctions, les tables à plusieurs dimensions, et divers types d'entiers (BYTE, INT16, INT32). occam 2 est beaucoup plus pratique et utile, occam 1 gardant un caractère exploratoire ; toutefois, le compilateur occam 1 ayant été écrit en occam 1, cela prouvait déjà qu'occam 1 pouvait suffire à diverses applications de taille modeste.
  • occam 2.1 (1994) fut la dernière contribution d'INMOS, influencée par une proposition antérieure de Geoff Garett dénommée occam91 puis occam 3 ; une définition révisée de cette proposition fut distribuée pour commentaires, mais cet occam 3 ne fut pas totalement implémenté. Il 2.1 introduit notamment :
    • la nomination de types (DATA TYPE x IS y)
    • la nomination d'articles (normaux ou compressés)
    • l'assouplissement de certaines règles de conversion
    • de nouveaux opérateurs (ex: BYTESIN)
    • les tableaux de canaux et leur retypage ;
    • la possibilité pour les fonctions de rendre une table de taille imposée.
  • occam-π désigne la variante d'occam proposée par les dernières versions de KRoC (pour Kent Retargetable occam Compiler). L'addition du symbol "π" (pi) signale le que cet occam reprend diverses idées du pi-calcul. Il introduit notamment :
    • l'imbrication de protocoles
    • la création dynamique de processus
    • la mobilité de canaux, de données et de processus
    • la récursivité
    • l'héritage de protocoles
    • les constructeurs de tables
    • l'extension des rendez-vous.

Voir aussi

Articles connexes

Liens externes

Références

  1. Note technique d'inmos sur TDS
  2. http://www.moria.de/~michael/fe/folding.html
  3. (en) Ericsson-Zenith, occam 2 Reference Manual, Prentice-Hall, (ISBN 0-13-629312-3)
  • Portail de la programmation informatique
Cet article est issu de Wikipedia. Le texte est sous licence Creative Commons - Attribution - Partage dans les Mêmes. Des conditions supplémentaires peuvent s'appliquer aux fichiers multimédias.