Learning path

Full curriculum

Full curriculum

Unit content

Task parallelism and fork-join execution

Task parallelism expresses a computation as units of work that may execute independently when their dependencies allow it.

A common model is fork-join. A running task forks child tasks, allowing them to execute concurrently, then joins them before using their combined results.

For example, to sum an array recursively:

sum(A):
    if A is small: return sequential_sum(A)
    fork left  = sum(first half of A)
    right      = sum(second half of A)
    join left
    return left + right

The two recursive halves have no data dependency and may run simultaneously. The final addition depends on both results.

Forking does not require one operating-system thread per task. A runtime can maintain many logical tasks and schedule them onto a smaller worker pool.

Nested fork-join naturally creates a dependency tree or DAG. The useful parallelism comes from the structure of that graph; the runtime's job is to map ready tasks onto available processors.

Creating tasks has overhead, so practical programs stop subdividing once work becomes small enough that sequential execution is cheaper.