简体   繁体   中英

ForkJoinTask: Order of join()-ing

The JavaDoc of ForkJoinTask says:

[R]eturns (joins) should be performed innermost-first. For example, a.fork(); b.fork(); b.join(); a.join(); is likely to be substantially more efficient than joining a before b.

I can't quite get my head around as to why (and in which circumstances) the order of join() s would matter, assuming I need to join a and b and get their results before continuing my computations.

Specifically, I have a couple dozens fork() ed tasks and I need to wait for all of them to return their result; much like invokeAll() would do, but I can still perform some work after fork() ing but before join() ing, so I implemented something like a joinAll() to be called only when I know that I cannot continue without the results from the forked tasks.

The question is, how should this joinAll() be implemented? Does it matter in which order this code actually calls join() on the tasks?

While preparing the ForkJoin-Framework for a lecture, I also stumbled upon this statement in the docs and wanted to know why it is that way.

First, I want to note, that I do not have the definitive answer to your question, but want to share what I found:

In the original paper written by Doug Lea ( http://gee.cs.oswego.edu/dl/papers/fj.pdf ), his implementation of the Work-Stealing algorithm is described more in detail in section 2.1: Subtasks generated by worker threads (using fork ) are pushed onto their own deque . The worker threads process their own deque LIFO (youngest-first), while workers steal from other deques FIFO (oldest-first).

And then the important part I think is: "When a worker thread encounters a join operation, it processes other tasks , if available, until the target task is noticed to have completed (via isDone). All tasks otherwise run to completion without blocking."

Therefore, it is more efficient to first join on the tasks which the worker itself will process next, instead of join ing on other tasks which might be stolen from other workers. Otherwise there is probably more thread management overhead due to potential context switches and lock contention.

At least for me, this reasoning would make sense regarding the description in the JavaDoc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM