Programming in occam [Web Edition 2001] 0137297734, 9780137297733

This book was published in the Prentice Hall International Series in Computer Science in 1988, and is no longer in print

250 34 750KB

English Pages 186 Year 1988

Report DMCA / Copyright

DOWNLOAD FILE

Polecaj historie

Programming in occam [Web Edition 2001]
 0137297734, 9780137297733

Table of contents :
Contents
Preface
An introduction to occam
Programming structures
Local time
Formatted input and output
In place of interrupts
Parallel matrix multiplication
Parallel sorting
Conway's game of Life
Huffman minimum redundancy coding
The occam notation
Codes of the programs
Input and output routines (text)
Terminal interrupt management (text)
Parallel matrix multiplier (text)
Parallel sorter (text)
Conway's game of Life (text)
Simple Huffman coder (text)
Adaptive Huffman coder (text)
Index

Citation preview

Contents

Prefa e 1 An introdu tion to o

am

Pro esses that do nothing Sequential pro esses Parallel pro esses Data de larations Arrays Pro ess de larations Loops and arrays of pro esses Expressions

ix 1

1 2 3 6 7 9 10 13

2 Programming stru tures

16

3 Lo al time 4 Formatted input and output

36 40

5 In pla e of interrupts

46

6 Parallel matrix multipli ation

58

Simple sequential pro esses Simple parallel pro esses Syn hronization by ontrol signals Pro esses that evaluate expressions Using parallelism as a tool for program modularity Using parallelism to resolve stru ture lash Output routines Input routines

Managing terminal input Managing terminal output Managing e hoing Con guration dire tives

vii

16 17 19 24 26 28 40 43

47 49 52 55

Contents

viii

7 Parallel sorting

65

8 Conway's game of Life

82

Sorting strategy Components of the sorter Monitoring strategy Component pro esses Display management The Life board Observation and ontrol Life

9 Hu man minimum redundan y oding

Representing a oding tree Constru ting a oding tree En oding and de oding using a oding tree Adapting the ode to the message

10 The o

am notation

Mi ro-syntax and layout Notation Pro esses Assignment Communi ations Real-time pro esses Constru ted pro esses De larations Named pro esses Expressions Ve tor expressions Implementation dependen ies Con guration dire tives Index of de nitions

65 67 70 74 76 83 90 98

99

101 103 107 114

124

124 126 127 127 128 129 129 132 134 135 138 139 140 142

Codes of the Programs

143

Index

181

Input and output routines Terminal interrupt management Parallel matrix multiplier Parallel sorter Conway's game of Life Simple Hu man oder Adaptive Hu man oder

144 148 151 154 162 170 175

Prefa e

This is a book about ertain sorts of parallel program. It is ertainly not about parallel omputers, nor is it really about the parallel programming language. Hardly any of it is about writing programs to run faster by being exe uted in parallel. Long before programmers had made any signi ant progress with the omplexities of programming single pro essor sequential omputers, they knew that the job was only made more omplex by trying to get the omputer to do two things at on e. The parts of an operating system responsible for keeping as many as possible of the peripheral devi es in on urrent a tivity are always the hardest to understand, and the tri kiest to get right. The problems needing solution are rapidly be oming more numerous and diÆ ult. It used to be that the management of on urren y was undertaken on the large s ale: reation of new pro esses, and syn hronization and s heduling of their a tions were ne essarily expensive in omparison to the real work done. These are onditions that seem to persist in the onstru tion of operating systems and of ontinent-wide ommuni ation networks, where pro esses are

onsequently long-lived and intera t as infrequently as an be ontrived. Su h are not the onditions experien ed by programmers of multi-pro essor omputers, where it be omes feasible to reate large numbers of ephemeral pro esses, and desirable that they ommuni ate frequently. A great many me hanisms have been suggested for the taming of on urren y, su h as semaphores, data monitors, ondition queues,

riti al regions, remote pro edure alls and rendezvous, even the dis iplined use of shared store. In ea h ase, the aim is to get several

o

am

ix

Prefa e

x

pro esses to o-operate, rather than interfere with ea h other. The me hanism is to redu e the amount of on urren y in the program by forbidding ertain sequen es of exe ution. The essen e distilled from these experiments by a number of theoreti ians is that the only way to make pro esses o-operate, usefully to ommuni ate information, is to arrange that their a tions be syn hronized when they need to intera t. The language inherits the tradition of theoreti al study, being more than reminis ent of re ent work on the mathemati s of syn hronization. It is intended by its devisers as the `assembly ode' of the INMOS transputer, a mi ropro essor designed to be used in relatively large numbers to make a single ma hine, yet apable of managing a large number of on urrent tasks within the one pro essor. The programmer is therefore en ouraged to think of pro ess reation, and of syn hronization and s heduling operations, as being as heap as any other `primitive' a tions. Even on a onventional pro essor, neither pro ess reation nor s heduling need be any more expensive than, say, pro edure invo ation. This startling s ale of osts gives the programmer mu h greater freedom of expression, and leads to an una

ustomed programming style. If you think that this book is about anything, I would prefer that you think it is about this style. The book begins with an introdu tion to suÆ ient to make the rest of the work intelligible to anyone who is already able to write and understand sequential programs. Some idioms are exer ised to help to give you an understanding of the way the language

an be used. The bulk of the text is devoted to a number of sizeable examples; these are programs written to give me material to dis uss in tea hing the use of . At the ba k of the book you will nd a on ise summary of the language, drawn from material in the , published in this same series. Finally, there are reprodu ed the omplete odes of the larger examples. I do not expe t that anyone might want to read hundreds of lines of ode, but their presen e may make it easier to settle ambiguities in the presentation in the text.

o

am

o

am o

am

o

am

o

am

Programming Manual

*

*

*

Several people will be ontent to believe that they en ouraged me to put this material between overs, some of them did, for whi h I am duly grateful, but I would not dream of burdening anyone else with a suspi ion of the responsibility for su h inadequa ies as remain.

1

An introdu tion to o

am

As far as will on ern us here, an o

am program is simply a pro ess, whi h may have some free identi ers that have spe i meanings dependent on the omputer on whi h the program is to be run. A pro ess des ribes some a tions that are to be performed: that is, it is the expression of an algorithm. Ea h pro ess may be either a primitive pro ess, or a omposite pro ess onsisting of a number of de nitions and simpler omponent pro esses bound together by pro ess onstru tors. The stru ture of onstru ted pro esses is indi ated by a xed layout of the sour e text, with ea h omponent appearing on a new line, slightly indented from the keyword that introdu ed the whole onstru tion. Pro esses that do nothing The simplest of the primitive pro esses is SKIP, whi h is the pro ess that does nothing at all. In many programming languages, you are obliged to write nothing (that is, not to write anything at all) if you want `nothing' done; you will see later that SKIP serves as useful a purpose in o

am as that of zero in the de imal notation for numbers. The pro ess STOP also does `nothing', but unlike SKIP it fails to terminate. You an think of it as being what happens when something goes wrong, like a deadlo k, or some illegal ma hine operation. Nothing an happen in a sequential pro ess after it has stopped, but things an happen in parallel with a stopped pro ess. You might not expe t to write the STOP pro ess very often in your programs, but it is the rational thing to do when something unexpe ted happens, be ause it ensures that the part of a network of pro esses that has failed is brought to a standstill without a e ting other pro esses, at

1

2

An introdu tion to o

am

least until they ome to depend on the broken part. It is also useful to have STOP around so as to be able to des ribe the e e t of ompound pro esses that `go wrong', for example by be oming deadlo ked. A pro ess is said to be deadlo ked if there is nothing whi h it is able to do next, but it has not nished properly. A parallel program whi h be omes deadlo ked typi ally does so be ause ea h of its pro esses is waiting for one of the others to do something. Sequential pro esses In programs whi h exe ute sequentially, the work is done by assigning values to variables, and subsequently basing de isions on the values of those variables. The o

am assignment has the form variable := expression

Ea h expression has a value, as explained later, whi h is just a bit pattern of the size of a `word' on your omputer, and every variable is

apable of storing a word sized bit pattern. Of ourse, there are operators whi h treat these bit patterns as if they represented numbers, or truth values, or hara ters, but no type distin tion is enfor ed by the language or its ompilers. A sequen e of operations is des ribed by writing them one under the other, under and slightly indented from the keyword SEQ. The sequen e exe utes by exe uting ea h of its omponents in the order in whi h they are written. Of ourse, if there are no omponents at all, then the sequen e does nothing, and behaves just like SKIP. Thus SEQ x y x z x

:= := := := :=

3 x + 7 x + 6 x + 1 (y + z) / 2

has the overall e e t of setting ea h of the variables x, y , z to 10, albeit in a somewhat perverse way: rst x is set to three, then y to seven more than x, then x is hanged to nine, z is set to one more than it, and nally x is set to the average of y and z , whi h is of

ourse also ten. De isions based on the values of variables are made by a onditional pro ess. This onstru tion onsists of the keyword IF written above a list of omponents, ea h slightly indented. Ea h omponent

Sequential pro esses

3

is either another onditional nested within the rst, or onsists of an expression (the ondition) and, below the ondition and a little further indented, a pro ess. The whole onditional exe utes by looking down the list of omponents, and the omponents of nested onditionals, until a ondition is found whose value is TRUE. If one is found then the orresponding pro ess and only that pro ess is exe uted, and the whole onditional terminates. It is an error for no ondition to evaluate to TRUE, for example if there are no omponents, so in that ase the onditional stops. IF

n < 0 sign := -1 n = 0 sign := 0 n > 0 sign := 1

sets the value of the variable sign to one of minus one, zero, or plus one, a

ording as the variable n has a negative, zero, or positive value. Sin e it is de ned that the textually rst of the pro esses orresponding to a TRUE ondition is sele ted, the pro ess IF

n = 0 sign := 0 n = AFTER

The value of a < b is TRUE if a is less than b a = b if a is not less than b a > b if a is more than b a b if a is not the same as b and is FALSE otherwise. Let h be the smallest positive integer that is too large to have a twos- omplement representation as a word sized bit-pattern. The value of a AFTER b is TRUE if a < b and (a b) < h or a > b and (b a) > h and is FALSE otherwise. Ea h bit in the value of an expression in a logi al operator logi al = /\ \/ >
< >< >
The value of a > b a displa ed right by b bit positions provided that the value of b is not negative. Bits in a pattern shifted left are moved to more signi ant positions, and in a pattern shifted right are moved to less signi ant positions. Va ant bit positions are lled by zero bits, and bits shifted past the boundary of the word are dis arded.

Ve tor expressions

A ve tor expression has a value whi h is a nite sequen e of values. ve torexpr = name string table sli e

A name has a ve tor value if it is bound by a onstant de nition to a

onstant ve tor, in whi h ase the value is that onstant ve tor; by a VALUE ve tor formal parameter, in whi h ase the value is that of the

orresponding a tual parameter; by a variable ve tor de laration or by a VAR ve tor formal, in whi h ase the value is the ve tor of values most re ently stored in the variables. The value of a string is the onstant byte ve tor des ribed above. The value of a table expression 







table = TABLE [ BYTE expression , expression ℄

is also a onstant ve tor, with as many omponents as there are omponent expressions, the value of ea h omponent being the value of the orresponding expression. Ea h expression must be a ompilation onstant. If the word BYTE appears inside the left bra ket, the value of the table is a ve tor of byte onstants, the value of ea h omponent of whi h is the least signi ant eight bits of the value of the

orresponding expression. A single value an be sele ted from a ve tor by subs ription sele tion = ve torexpr sele tor 



sele tor = [ BYTE expression ℄

139

Ve tor expressions

The value of the sele ting expression must be non-negative and less than the number of omponents in the ve tor. The omponents of a ve tor are indexed onse utively from zero at the rst omponent, and the value of a sele tion is that omponent of the value of the ve tor indexed by the value of the expression. A sele tor sele ts a word from a word ve tor, unless BYTE appears inside the left bra ket in whi h ase it sele ts a byte from a byte ve tor. A sli e of a ve tor is also a ve tor. sli e = ve torexpr sli er 



sli er = [ BYTE expression FOR expression ℄

A word ve tor sli ed by a word sli er is a word ve tor, and a byte sli e, with BYTE inside the left bra ket, of a byte ve tor is a byte ve tor. The rst omponent of the value of the sli e is that indexed by the value of the rst expression of the sli er. The number of omponents in the value of a sli e is the value of the se ond expression in the sli er, whi h must be positive. The orresponden e is su h that p[q FOR r℄[s℄ = p[(q) + (s)℄ p[BYTE q FOR r℄[BYTE s℄ = p[BYTE (q) + (s)℄ For a sli e to be valid, ea h valid sele tion from it must be a valid sele tion from the ve tor, a

ording to these rules.

Implementation dependen ies

An implementation may require some expressions to have values whi h are readily determinable during ompilation. Any name whi h o

urs in su h a ompilation onstant must be bound by a onstant de nition. The expressions in onstant de nitions and tables must always be onstants. Conventional implementations will require the sizes of de lared ve tors of variables and hannels, and the repli ation

ounts of PAR repli ators also to be onstants. The language des ribed in the o

am Programming Manual allows of byte sele tion and sli ing of word ve tors and vi e versa. The meanings of programs whi h use these depend on an implementation parameter N whi h is the number of bytes in a word. The values of word and byte ve tors are identi ed in su h a way that p[BYTE q℄ = (p[(q)/N℄ >> ((q)\N)) /\#FF

and onsistently for sli es.

140

The o

am notation

Con guration dire tives

Although an o

am program may simply be a pro ess, the Programming Manual de nes onstru tions for on guring stand-alone programs. program = system allo ation global singleton program A program may be a system of pro esses to be run on di erent pro essors, or it may be a singleton to be run on a single pro essor. (An allo ation in ludes the information ne essary for a ompiler to t the singleton to its pro essor. Although the Programming Manual des ribes this, it is of no interest in this book so left undes ribed.) De larations whi h pre ede a distributed program must themselves be distributable globals = onstdefs hande ls pro de l

so may not de lare any variables. Their meaning is exa tly the same as it would have been in an ordinary blo k. A system of distributed pro esses is divided between pro essors by indi ating the distribution of the outermost parallel onstru ts. system = PLACED PAR PLACED PAR repli ator z }| { program program |

{z

}

A system exe utes by the on urrent exe ution of its omponent programs. The annotation PLACED does not alter the exe ution of a parallel ex ept to indi ate that ea h omponent is to be exe uted by a di erent (set of) pro essors. A singleton is to be exe uted by a single pro essor. singleton = pro ess PRI PAR de laration : z }| { pro ess singleton | {z }

A singleton may either be a pro ess to be exe uted by its pro essor, or an asymmetri parallel. An asymmetri parallel exe utes by the on urrent exe ution of its omponent pro esses, in the same way as the orresponding symmetri onstru t, ex ept that it is guaranteed that no omponent exe utes unless all synta ti ally pre eding omponents are unable to

Con guration dire tives

141

pro eed, either be ause they are waiting for ommuni ation or be ause they have terminated. An implementation may impose a small limit on the number of omponents in an asymmetri parallel. A de laration pre eding an asymmetri parallel has exa tly the same meaning as if the parallel were symmetri .

142

The o

am notation

Index of de nitions a tion a tual a tuals allo ation alternative arithmeti assignment asso atomi blo k boolean

hana tual

hande l

hande ls

hanformal

hanformals

hannel

hara ter

hoi e

omparison

onditional

onsta tual

onstdef

onstdefs

onstformal

onstformals

onstru t de laration delay expression formal formals globals guard guarded input literal logi al

127 134 134 140 130 136 127 136 131 132 137 135 133 133 135 135 133 125 129 137 129 134 132 132 134 134 129 132 129 136 134 134 140 131 130 128 135 137

logi al lines 124 monop 136 name 124 numeral 125 output 128 parallel 130 physi al lines 124 pro de l 134 pro ess 127 program 140 rand 135 rator 136 repetition 132 repli ator 131 sele tion 138 sele tor 138 sequen e 129 shift 138 signed 136 signednumeral 125 singleton 140 sli e 139 sli er 139 sour e 128 substitution 134 symmetri alt 130 system 140 table 138 target 128 timer 129 vara tual 135 varde l 133 varde ls 133 varformal 135 varformals 135 variable 133 ve torexpr 138 ve torvar 133

Codes of the Programs

In the following pages are the programs referred to in the orrespondingly named hapters earlier in the book. They are trans ribed as faithfully as ir umstan es permitted from originals omposed and exe uted using an o

am programming system. In the trans ription, the stru ture of the text has been removed, leaving only the sequen e of lines whi h you see here. It is harder to read ` at', un-folded o

am on paper than it is to read a stru tured text using an editor that allows exploration of that stru ture. In re ognition of this diÆ ulty there is, on the title page of ea h se tion, a summary of the gross stru ture of the ode whi h follows in that se tion.

143

Input and output routines

PROC write.string(CHAN output, VALUE string[℄) -- Write the hara ters of the string[℄ to the output PROC write.signed(CHAN output, VALUE n, field.width) -- Write a signed de imal representation of n to the output, -- right justified to o

upy field.width hara ter spa es PROC ----

read.signed(CHAN input, VAR n, ok) Read an (optionally signed) de imal numeral from the input returning the orresponding value in n, and TRUE or FALSE in ok a

ording as the onversion worked or not

PROC ----

read.line(CHAN keyboard, s reen, VAR s[℄) Constru t a string in s[℄ from the printable hara ters read from keyboard and e hoed to s reen. The string finishes at a arriage return.

144

Input and output routines

145

PROC write.string(CHAN output, VALUE string[℄) = -- Write the hara ters of the string[℄ to the output SEQ hara ter.number = [1 FOR string[BYTE 0℄℄ output ! string[BYTE hara ter.number℄ :

PROC write.signed(CHAN output, VALUE n, field.width) = -- Write a signed de imal representation of n to the output, -- right justified to o

upy field.width hara ter spa es VAR tens, width : -- tens will be a signed power of ten SEQ IF n >= 0 SEQ tens := -1 width := 1 -- ount a minimum of one digit n < 0 SEQ tens := 1 width := 2 -- ount a sign and a minimum of one digit WHILE (n / tens) > 8)) /\ 1)

:

SEQ VAR event, number : -- first fill the tree SEQ TIME ? event number := (event /\ mask) \/ 1 -- initialize the random number SEQ i = [0 FOR number.of.leaves℄ SEQ event := event + se ond shift(number) -- pi k a new number up ! TRUE; number -- send it into the tree TIME ? AFTER event -- and wait for a se ond up ! FALSE VAR event : -- then empty the tree SEQ TIME ? event SEQ i = [0 FOR number.of.leaves℄ SEQ event := event + se ond down ? ANY; ANY -- take a number from the tree TIME ? AFTER event -- on e a se ond down ? ANY; ANY :

Parallel sorter DEF root = 0 , first.fork = root , first.leaf = first.fork + number.of.forks : CHAN

up.a[number.of. hannels℄, down.a[number.of. hannels℄, up.b[number.of. hannels℄, down.b[number.of. hannels℄, probe[number.of.probes℄, all.probes :

PAR driver(up.a[root℄, down.b[root℄) PAR i = [first.fork FOR number.of.forks℄ fork(up.b[i℄, down.a[i℄, down.b[(2*i)+1℄, up.a[(2*i)+1℄, down.b[(2*i)+2℄, up.a[(2*i)+2℄) PAR i = [first.leaf FOR number.of.leaves℄ leaf(up.b[i℄, down.a[i℄, probe[number.of. hannels + (i - first.leaf)℄) PAR i = [root FOR number.of. hannels℄ monitor(up.a[i℄, down.a[i℄, up.b[i℄, down.b[i℄, probe[i℄) multiplex(probe, all.probes) display(all.probes, terminal.s reen)

161

Conway's game of Life

PROC al ulate.next.state(CHAN link[℄, VALUE in[℄, state, VAR next.state) PROC broad ast.present.state(CHAN link[℄, VALUE out[℄, state) PROC ell(CHAN link[℄, VALUE in[℄, out[℄, CHAN ontrol, sense) PROC initialize(VALUE x, y, VAR in[℄, out[℄) PROC move. ursor(CHAN s reen, VALUE x, y) PROC lear.s reen(CHAN s reen) PROC initialize.display(CHAN s reen) PROC lean.up.display(CHAN s reen) PROC display.state(CHAN s reen, VALUE x, y, state) PROC generation(CHAN s reen, ontrol[℄, sense[℄, VAR a tive) PROC edit(CHAN keyboard, s reen, ontrol[℄) PROC display.a tivity(CHAN s reen, VALUE a tivity) PROC new.a tivity(VAR a tivity, VALUE h) PROC ontroller(CHAN keyboard, s reen, ontrol[℄, sense[℄) PAR

ontroller( : : : ) PAR x = [0 FOR array.width℄ PAR y = [0 FOR array.height℄ SEQ initialize( : : : )

ell( : : : )

162

-- ontrol pro ess -- board

163

Conway's game of Life

DEF dead = 0,

alive = NOT dead :

-- possible states of ea h ell

DEF radius = 1 , -- radius of the `sphere of influen e' diameter = (2 * radius) + 1 , neighbours = (diameter * diameter) - 1 : -- onsequent number of neighbours

PROC al ulate.next.state(CHAN link[℄, VALUE in[℄, state, VAR next.state) = VAR ount : -- number of living neighbours SEQ VAR state.of.neighbour[neighbours℄ : SEQ PAR i = [0 FOR neighbours℄ -- re eive present state link[in[i℄℄ ? state.of.neighbour[i℄ -from ea h neighbour

ount := 0 SEQ i = [0 FOR neighbours℄ IF state.of.neighbour[i℄ = alive

ount := ount + 1 -- ount the number alive state.of.neighbour[i℄ = dead SKIP IF

ount < 2 -- if too few next.state := dead -die from isolation

ount = 2 -- if exa tly two next.state := state -this ell is stable

ount = 3 -- if exa tly three next.state := alive -give birth if dead

ount > 3 -- if too many next.state := dead : -die from over rowding

PROC broad ast.present.state(CHAN link[℄, VALUE out[℄, state) = -- satisfy ea h neighbour's need to know this ell's state PAR i = [0 FOR neighbours℄ link[out[i℄℄ ! state :

164

Codes of the Programs

DEF set.state = 1, ask.state = 2, terminate = 3 : PROC ell(CHAN link[℄, VALUE in[℄, out[℄, CHAN ontrol, sense) = -- al ulate the state of a single ell on the board VAR state, instru tion : SEQ state := dead -- the whole board starts off dead

ontrol ? instru tion WHILE instru tion terminate SEQ IF -- on instru tion instru tion = set.state

ontrol ? state -a

ept a new state instru tion = ask.state VAR next.state : SEQ -or al ulate the next state PAR broad ast.present.state(link, out, state) SEQ

al ulate.next.state(link, in, state, next.state) sense ! (state next.state); next.state -announ e it to the ontroller state := next.state -and move on a generation

ontrol ? instru tion :

165

Conway's game of Life

DEF array.width = 50, array.height = 20 : DEF number.of. ells = array.height * array.width , number.of.links = neighbours * number.of. ells : PROC initialize(VALUE x, y, VAR in[℄, out[℄) = -- initialize the link indire tion arrays for the ell at x,y SEQ delta.x = [-radius FOR diameter℄ -- offset of neighbour SEQ delta.y = [-radius FOR diameter℄ -- in two dimensions VAR dire tion : -- -4