From: | Anton Lokhmotov <al407@cam.ac.uk> |
Newsgroups: | comp.compilers |
Date: | Mon, 13 Aug 2007 13:52:09 +0100 |
Organization: | Compilers Central |
References: | 07-08-01607-08-021 07-08-024 07-08-034 |
Keywords: | optimize, parallel |
Posted-Date: | 15 Aug 2007 11:40:40 EDT |
Hello,
I'd like to thank everyone who joined the discussion on vector
assignment semantics. It's been quite elucidating.
All the papers on Fortran 8x I read so far mention the parallel
semantics. But I decided to check on the PL/I semantics. In "The early
history and characteristics of PL/I" (HOPL-I, 1978, pp. 570-571),
George Radin wrote that he original PL/I semantics was serial but was
changed to parallel in the ANSI-1976 standard. Radin claims that the
parallel semantics seems more natural to programmers, while the
sequential semantics does not require temporaries (as Glen
Herrmannsfeldt has noted), possibly leading to more efficient code on
machines of the time. Today, few would argue against supporting
"naturalness" (even if at the expense of space).
It's interesting to point out a recent variation on the topic by
Codeplay Software. In Codeplay's Sieve C++, the programmer can place
a code fragment inside a special sieve block, thereby instructing the
compiler to /delay/ writes to memory locations defined outside of the
block (global memory) and apply them /in order/ on exit from the
block.
For example, by writing:
float *pa , *pb; ...
sieve { // sieve block
for (int i = 0; i < n; ++i) {
pb[i] = pa[i] + 42;
}
} // writes to pb [0:n -1] happen on exit from the block
the programmer requests to delay the writes to global memory locations
referenced by pb[0],..., pb[n-1] until the end of the block. In this
example, we can also say that the programmer requests the semantics of
the Fortran 90 vector notation pb[0:n-1] = pa[0:n-1] + 42, which
differs from the sequential if vectors pa[0:n-1] and pb[0:n-1] overlap
(as they may well do in C!)
In this context, delaying writes may not seem natural and lead to
unexpected results. For example:
int main () {
int a = 0;
sieve {
int b = 0;
a = a + 1; b = b + 1; print (a, b); // prints 0,1
a = a + 1; b = b + 1; print (a, b); // prints 0,2
}
print (a); // prints 1
}
the last statement prints 1, not 2. (For more details please see
(http://www.cl.cam.ac.uk/~al407/research/papers/eupar07.pdf)
However, the sieve semantics is deterministic, hence predictable and
repeatable. So really, it's just a generalisation of the parallel
vector notation to (possibly) several statements in a block.
Regards,
Anton.
Return to the
comp.compilers page.
Search the
comp.compilers archives again.