Occam (idioma)

Occam
Data da primeira versão 1983
Paradigma Programação simultânea , computação distribuída , imperativo
Desenvolvedor Inmos
Última versão 2.1 (1988)
Influenciado por Comunicação de processos sequenciais

A linguagem de programação Occam é uma linguagem de programação adaptada à arquitetura paralela, que surgiu em 1983. Foi desenvolvida pela Inmos para a programação de suas arquiteturas paralelas de Transputer , mas também foi portada para outras plataformas.

O nome é uma homenagem a Guilherme de Occam (às vezes soletrado Ockham) e ao princípio metodológico da navalha de Occam .

A linguagem Occam é uma linguagem procedural que oferece, além da execução de instruções sequencialmente (com SEQ), a execução de instruções em paralelo (com PAR) e até mesmo o “paralelismo assíncrono” de processos (com ALT) para um não execução determinística de um de muitos. A execução no PAR dos processos é feita com nomeações, como na Ada .

Occam também contém as "ordens guardadas" de Edsger Dijkstra  : um processo só é iniciado se o valor de sua guarda, avaliado pelo sistema, for verdadeiro.

O Transputer Development System (TDS) da Inmos foi a ferramenta de desenvolvimento clássica para esta linguagem, mas era possível usar Parallel C ou outras ferramentas. O editor TDS permitiu o dobramento de código , o que foi muito inovador.

Princípios básicos

Em Occam, o recuo é significativo, o que evita os marcadores de início e fim de blocos comuns a outras linguagens herdadas de Pascal e C (início ... fim, {...}, loop ... endloop etc. ). Uma expressão é encerrada por um fim de linha. Várias expressões podem ser agrupadas em um bloco onde todas as linhas começam no mesmo recuo.

A comunicação entre processos paralelos é feita com "canais" definidos pela expressão "CHAN OF". Esses canais são implementados pelos links bidirecionais seriais rápidos (2 Mb / s, 4 links / Transputer, comunicação independente da CPU). Um processo envia dados pelo canal com "!" enquanto outro processo recebe os dados com "?", transmissão e recepção sendo síncronas:

keyboard ? c screen ! c

SEQ apresenta uma lista de expressões que são avaliadas em sequência, uma após a outra. Exemplo:

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

PAR anuncia uma lista de expressões que provavelmente serão avaliadas simultaneamente. Exemplo:

PAR p() q()

ALT indica uma lista de declarações mantidas . Os protetores são combinações de condições binárias e entrada no canal. Uma alternativa entre aqueles cujas condições são verdadeiras e cujos canais de entrada estão prontos, é executada. Exemplo:

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

Este exemplo lerá os dados dos canais "c1" e "c2" (se estiverem prontos) e os mesclará em um único canal de saída "mesclado". Se o contador countN atingir 100, a leitura do canal N será desabilitada. Uma solicitação sobre o estado do canal será respondida pelos dois contadores.

Exemplos de código

Alguns exemplos reais de código

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

Outro exemplo :

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

Exemplo de um multiplexador de canal:

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

Evolução

Veja também

Artigos relacionados

links externos

Referências

  1. Nota técnica Inmos sobre TDS
  2. http://www.moria.de/~michael/fe/folding.html
  3. (en) Ericsson-Zenith , Occam 2 Reference Manual , Prentice-Hall,1988( ISBN  0-13-629312-3 )