When a program is running over multiple processors or
processing cores then it is important to be able to map where data are flowing.
One way in which data flows can be translated into programming language semantics
is though argument passing to subroutines. In the absence of global variables,
data transfer to and from a subroutine straightforwardly can be directly related to
communication to and from another processor. In PM, the emphasis is on data
parallelism through the for
statement.
for index in array do
index=process(index)
endfor
So what are the rules governing data flow into and out of
this statement? These are primarily based around variable locality.
x:= 1
for index in array do
y:=func(index)
index=process(x,y)
endfor
Here x is relatively global to the for statement and y is local to it (a variables scope only extends to the end of the statement block in which it is defined). There are two ways to import data into the for statement and two ways to get it back out.
To import data you either:
- Refer to a relatively global variable from within the statement - such as accessing x in the above example
- Specify the data in the iteration clause – array above.
To export data you either:
- Assign to an iteration variable – such as index above. This, of course, only works if the variable is iterating over a modifiable value – an array or slice
- Use a let clause
Including a let
clause at the end of a for statement
defines named constant values in the enclosing scope. These can be used to
return values that are invariant across all invocations of the for statement
body – essentially the results of reduction or aggregation operations.
for index in array do
y:=func(index)
let
sum=sum::y
allvalues=@y
endfor
further_process(sum,allvalues)
This is the complete set of data transfers allowed for the for statement. Other statements allow different communication patterns - such as parallel find, to be discussed in a future post.
Comments
Post a Comment