XML

kent logo

CO538 Anonymous Questions and Answers Keyword Index

This page provides a keyword index to questions and answers. Clicking on a keyword will take you to a page containing all questions and answers for that keyword, grouped by year.

To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.

Keyword reference for par

2010

Question 60 (2010):

Submission reference: IN1956

I'm experiencing an embarrassingly stupid problem with reading a value on a channel into a variable.

  PROC a (CHAN INT a?)
    CHAN INT b:
    INT output:
    SEQ
      some.proc (a?, b!)
      b ? output
      ...  do stuff with output
  :

"some.proc" hangs when it outputs on b because I guess nothing picks up the value. Can you please suggest what I need to do to get this to work? The compiler warns about sequential input/output on b but I can't think how else to express that I just want the value on that channel assigned to a variable.

Answer 60:

The code you have above tries, in SEQuence, to output then input on the same channel (b). Because channel communication is synchronous, the output (inside "some.proc") will just block, because there is no parallel process to communicate with. That process ("b ? output") cannot run until the call to "some.proc" completes, because of the SEQ, thus deadlock. The answer is to add some parallelism, e.g.:

    PROC a (CHAN INT a?)
      INT output:
      SEQ

        CHAN INT b:   -- only needed for the PAR (declare stuff only where needed)
        PAR
          some.proc (a?, b!)
          b ? output

        ...  do stuff with output
    :

This assumes that "some.proc" only outputs once on "b" and then terminates, else the "... do stuff with output" won't be able to run. If "some.proc" outputs repeatedly on "b" (and maybe never terminates), you would need something like:

    PROC a (CHAN INT a?)
      CHAN INT b:
      PAR

        some.proc (a?, b!)
  
        INT output:
        SEQ
          b ? output
          ...  do stuff with output
    :

On the other hand, if your "some.proc" does only output one value down the "b" channel, it's much simpler to return that value through a reference parameter – i.e. not to use a channel and the first PAR code above. Question 58 (2010) introduces the (non-examinable) concept of RESULT reference parameters, which would be ideal for this – for example:

    PROC some.proc (CHAN INT in?, RESULT INT answer)
      ...  puts some value into 'answer'
    :

    PROC a (CHAN INT a?)
      INT output:
      SEQ
        some.proc (a?, output)
        ...  do stuff with output
    :

The above code will work the same without the RESULT keyword qualifying the "INT answer" reference parameter. Having the keyword improves safety, since the compiler checks that "answer" is not used before it is given a value and that it is given a value (at least once) before "some.proc" terminates.

Keywords: channels , seq , par , result

Referrers: Question 56 (2011)

2007

Question 35 (2007):

Submission reference: IN1360

I have a question about SEQ and PAR... we've had Peter lecturing since the start of term, telling us to always use PARs wherever we can, unless we specifically need something to happen in order, in which case you use a SEQ. Which all makes perfect sense.

However, the other day, we had Fred lecturing, who implied that because of the overhead in setting up PARs, you shouldn't use them unless you actually needed them. We brought up this discrepancy in the lecture, and Fred said something along the lines of: in the exam, either is fine (unless the question is obviously specifically looking for something to happen in parallel or sequence).

He said that we should use our judgement in which to use in the exam, but I don't think we have any experience in this area - we don't have a grasp on the overhead of a PAR (I certainly don't), but Fred obviously does, due to writing occam compiler(s?).

I'm now a little confused, and I think other people are too, as to what I'm supposed to write in an either/or situation. Is either OK?

Answer 35:

No – I (Peter) carefully did not say to use PARs wherever we can! I said that whenever communications can be done is parallel, we must do so – otherwise, the ways in which the process can synchronise with the newtork in which it is embedded is needlessly constrained to happen in some SEQuential order. This can lead to needless delays (on the other processes trying to communicate) and, in the worst case, to a needless deadlock (which is unacceptable). For example, see the golden rule shown on slide 4 of the replicators slides.

I have also warned that executing pure compute code (i.e. any code not involving synchronisation with other processes) in parallel may lead to a slower executing system, so we should be careful. As Fred said, there are overheads in starting up, scheduling and shutting down parallel code – even though these are very small for occam-pi run-times (e.g. ten-or-so nanoseconds for compiled code). So, if the codes we are asking to run in parallel are very short (e.g. a single assignment), it may not be worth it. Further, it is only the run-time support for compiled occam-pi that currently takes advantage of multicore processors so that parallel computations can actually happen in parallel – and the extent of that physical cuncurrency is bounded by the number of cores present (mostly no more than two right now). Any more parallel processes released than the number of cores must be scheduled, in turn, on the available cores.

The rules of occam-pi ensure that the semantics of a PAR involving only pure computation are exactly the same as a SEQ. The former says "run these processes in any order, or at the same time, till they all finish" and the latter says "run these processes in the order written". If the compiler allows the PAR, then the processes to be run are independent from each other and any order, including the order written, is OK. So, if the overheads of going PAR are higher than the time benefits of running them at the same time (bearing in mind that we might only have two cores and, if using the current Transterpreter, no advantage is taken of the second core), run those small codes in SEQuence – it will be faster.

There will come a time, perhaps soon, when running pure computation statements in parallel will distribute over lots and lots of processor cores with a low enough overhead to make it worthwhile – just not yet! The PAR rules of occam-pi automatically restrict this only to codes that are safe for parallel execution, which is a plausible reason for starting to do this now. So, in answer to the final part of your question, either writing a SEQ or a PAR for low-level short-lived computations (so long as the PAR version breaks no rules) is OK for exam answers or assessment codes.

The time has already come when running long-lived processes in parallel is worthwhile, even for processors that are only dual-core. And ... as laid out in the golden rule and for the reasons stated above, when communication is involved and we can specify PAR, we must specify PAR.

Good question!   :)

Keywords: seq , par

2004

Question 60 (2004):

Hi, could you just give an explanation of how the following code works (taken from "sort_pump.occ"):

    PROC sort (CHAN OF BYTE in, out)
      [total - 2]CHAN OF BYTE c:
      PAR
        cell (in, c[0])
        PAR p = 1 FOR total - 3
          cell (c[p - 1], c[p])
        cell (c[total - 3], out)
    :

Thanks.

Answer 60:

This code creates a pipeline of processes (of `total - 1' cells) -- see slides 5-17 and 5-18. The two end cells are catered for specially (since these plug into the external environment -- via `in' and `out'). The cells between these are created using a replicated PAR. If you substitute a constant value for `total' (say 10), then expand and flatten the PAR replicator, it becomes a bit clearer:

    [8]CHAN OF BYTE c:
    PAR
      cell (in, c[0])

      cell (c[0], c[1])        -- PAR p = 1 FOR 7
      cell (c[1], c[2])        --   cell (c[p - 1], c[p])
      cell (c[2], c[3])
      cell (c[3], c[4])
      cell (c[4], c[5])
      cell (c[5], c[6])
      cell (c[6], c[7])

      cell (c[7], out)

Keywords: sort-pump , par , replicator

2003

Question 78 (2003):

I'm quite confused on how I can assign each philosopher an identity. I've modified the header of the PROC philosopher in the following way:

    PROC philosopher(CHAN OF INT id, CHAN OF BOOL left, right,down, up, CHAN OF MESSAGE report)

This means that the display PROC has 16 input channels. I'm not sure this is the right way of doing it.

Answer 78:

Assigning IDs to the philosophers is better done by simply using a ``VAL INT'', passed to each philosopher from the PAR replicator that sets the network up.

Communicating the ID to each philosopher (using the `id' channel you added) is certainly possible, but definitely not the simplest way.

Keywords: par , q7

2000

Question 2 (2000):

Is PAR used *only* when connecting all PROCs to build the final one big PROC?

Answer 2:

No. See the above answer for an example use of PAR to build some very fine-grained parallel code. It all depends on the code you write into the components of the PAR. In the above, they are short-lived primitives (a channel input and an assigment). If the statements controlled by the PAR and instances of PROC calls and those PROCs are long-lived (e.g. they contain loops - possibly infinite), then we get a long-lived process network. See, for example, slide 4-26 from the course notes. [BTW - has everyone found the deliberate mistake on slide 4-26?]

occam lets us easilly build parallelism at any level in the system - this is much more flexible than Java, for example, whose Thread mechanism is considerably more complex to set up.

Keywords: par , process-networks

Valid CSS!

Valid XHTML 1.0!

This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
Last modified Mon May 20 13:50:28 2013
This document is maintained by Fred Barnes, to whom any comments and corrections should be addressed.