I know very little about how it all acutally works, but I was wondering if:
proc pi(n: int): float =
var ch = newSeq[float](n+1)
parallel:
for k in 0..ch.high:
ch[k] = spawn term(float(k))
for k in 0..ch.high:
result += ch[k]
could be made easier for the user, by handling the gathering and returning of "term()" results,
something like the following:
proc pi(n: int): float =
parallel:
for j in 0..someLimitNr:
spawn[float] (term(float(j)))
# this retrieves the results of spawning term() as seq[float] in this case.
# If above was spawn(term(...)) that didn't specify a type,
# then there would be no results returned from term()
#
let theResults = sync()
for k in theResults:
result += k
In summary:
sync() or some suitable proc is used to return the collected results as a seq[T] or similar (only after all spawned procs are finished). An alternative to sync could be a block term, like parallelResult:
parallel:
for j in 0..someLimitNr:
spawn[float] (term(float(j)))
parallelResult:
let theResults = sync()
for k in theResults:
result += k
The terms don't have to be the same as parallel/spawn/sync, I am just thinking of how to make the overall "template" of the code simpler for the user.
Something like this is not hard to do, but it doesn't capture many use cases as the working set sizes and how the splitting of work is done is not abstracted over:
template forkAndJoin(n, fork, join: untyped) {.dirty.} =
var ch = newSeq[type(fork(0))](n)
parallel:
for k in 0..ch.high:
ch[k] = spawn fork(k)
for k in 0..ch.high:
join(result, ch[k])
forkAndJoin(n, term(float(k)), `+=`)
Food for thought. :-)