Lably
Skip to content

Fork–join model

Way of setting up and executing parallel computer programs

  • 2 min read
  • 2 chapters

Related on Lably

Through Recursion (computer science) and Pseudocode

By nesting fork–join computations recursively, one obtains a parallel version of the divide and conquer paradigm, expressed by the following generic pseudocode:

<b id="mwIQ">solve(problem)</b>: <b id="mwIg">if</b> problem is small enough: solve problem directly (sequential algorithm) <b id="mwIw">else</b>: <b id="mwJA">for</b> part <b id="mwJQ">in</b> subdivide(problem) <b id="mwJg">fork</b> subtask to <b id="mwJw">solve(part)</b> <b id="mwKA">join</b> all subtasks spawned in previous loop <b id="mwKQ">return</b> combined results

Examples

The simple parallel merge sort of CLRS is a fork–join algorithm.

mergesort(A, lo, hi): <b id="mwNA">if</b> lo < hi: <i id="mwNQ">// at least one element of input</i> mid = ⌊lo + (hi - lo) / 2⌋ <b id="mwNg">fork</b> mergesort(A, lo, mid) <i id="mwNw">// process (potentially) in parallel with main task</i> mergesort(A, mid, hi) <i id="mwOA">// main task handles second recursion</i> <b id="mwOQ">join</b> merge(A, lo, mid, hi)

The first recursive call is "forked off", meaning that its execution may run in parallel (in a separate thread) with the following part of the function, up to the join that causes all threads to synchronize. While the join may look like a barrier, it is different because the threads will continue to work after a barrier, while after a join only one thread continues.

The second recursive call is not a fork in the pseudocode above; this is intentional, as forking tasks may come at an expense. If both recursive calls were set up as subtasks, the main task would not have any additional work to perform before being blocked at the join.

Sign in to keep reading

One more chapter is free with a Lably account.

More in Computing and communication