But, simultaneous application of the function body to all elements is restrained by the data dependence among recursions. In the beginning, the value of the accumulation parameter is available only for the root node and the accumulation parameters for other recursions must be propagated along recursive calls. If recursive calls are in a function body, their results must be obtained along the return of recursive calls. For example, subexpression 1+n of the inorder function includes the accumulation parameter n. To evaluate 1+n in parallel, the values of n must be available on all processors. But the value of n is available only for the function application on the root node and the value of n for other recursions must be propagated along recursive calls. For another example, the value of s1 is obtained from the first recursive call. Results of the recursive calls can only be obtained along the return of recursive calls.
Observing the inorder function a little closer, there exist dependencies between recursive calls. The second recursive call uses s1, which is the result of the first recursive call, in its accumulation parameter 1+n+s1. If this dependency forces the recursive calls to be evaluated sequentially, parallel execution time of the function application becomes linear to the number of elements. But, in case of the inorder function, because any value of the accumulation parameter is not used to compute the second element of the result, we can get the values of s1 and s2 in bottom-up order without dependencies between sibling recursions. With the values of s1 and s2 first, we can execute the recursive calls of the function body in parallel.
To classify subexpressions of a function body based on their condition of
data parallel execution, we divide results of
recursive calls into
results and
results.
results
do not use any value of the accumulation parameters and
results
may use values of the accumulation parameters. In the inorder function,
s1 and s2 are
results, and t1 and t2 are
results.
Considering above observations, we classify subexpressions in a function body as follows. For convenience, we use colors to name them. They are classified along the written order.
If some Yellow expression uses any Black expression,
it means that there are multiple recursive calls in a function body and
a
result of a recursive call is used to evaluate an accumulation parameter for another recursive call.
In this case, the recursive calls cannot be evaluated in parallel
and the virtue of parallelization disappears because the parallel execution time
becomes linear to the number of elements.