[concurrency-interest] Java Fork/Join Framework
Thomas Hawtin
tackline at tackline.plus.com
Mon May 7 12:01:47 EDT 2007
Doug Lea wrote:
>
> Thomas Hawtin wrote:
>>
>> * That's an awful lot of types. Wouldn't the effort spent of
>> primitive support be better spent bullying the JVM people into
>> optimise boxing?
>
> [...]
>
> If we could teach everyone how to reliably write the kind
> of code illustrated in the sunOfSquares example in
> http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/forkjoin/ForkJoinTask.html
>
> then we wouldn't need most of these. (Although we'd still want some
> for prewired utilities like sorting.)
Can't most of that be abstracted? With a minimum sequential size, using
a reducer shouldn't be a problem.
I was thinking a general method like:
public static <T> T split(
ForkJoinPool pool, int len, int minSeq, SplitTask<T> split
)
And then the sumOfSquares example would become:
double static sumOfSquares(ForkJoinPool pool, final double[] array) {
return split(pool, array.length, 1024, new SplitTask<Double>() {
public Double slice(int lo, int hi) {
double sum = 0;
for (int i = lo; i <= hi; ++i) {
sum += array[i] * array[i];
}
return sum;
}
public Double combine(Double a, Double b) {
return a+b;
}
}
);
}
(Looking a ListTasks.reduce, a combined Mapper and Reducer would
simplify use a little.)
>> * Why List instead of Collection or Iterable?
>
> Because parallel recursive divide and conquer requires
> being able quickly to find midpoints breaking problems
> in half. Arrays and (RandomAccess) Lists provide this.
> Others don't, so you'd waste so much time linearly scanning
> to break up problems that you'd lose speedups for all but
> the heaviest code bodies. With lists and arrays, you can
> get very impressive speedups on MPs for ordinary
> reasonably small code bodies (like sums of squares for example).
I was thinking it's easy enough to convert a slow Collection or Iterable
into a RandomAccess List, but then I guess it's easy enough for the
caller too.
>> * I object to the static ForkJoinTask methods.
>>
>
> Do you object to static Thread methods? They use the same
> pattern for the same reason -- all the work in all ForkJoinTask
> methods is actually done via your Thread.currentThread(),
> which is specialized to ForkJoinPool.Worker.
Methods like yield? They only make sense on the current thread. The only
one I see like that is ForkJoinTask.getLocalQueueSize.
ForkJoinPool.getPool (which would be currentPool in Thread's convention)
seems unnecessary.
Tom Hawtin
More information about the Concurrency-interest
mailing list