Suppose an algorithm that receive an input array of $n$ elements and it performs a task over each element. All tasks are independent and take $O(k)$ each (being $k$ a variable). Since all tasks are independent this is a fully parallelizable problem.
I have a basic algorithm that uses the Divide and Conquer technique. It receive the input array $A$ and if $|A| > 1$ then it spawn a new thread to process the first half of $A$, and recursively call itself to process the second half. This recursions stops when the function is called with a single element, in which case it runs a series of steps that takes $O(k)$.
I´m using the Dynamic Multithreading model (Introduction to Algorithms, chapter 27) to analyze this algorithm. So, I have an execution graph with n "leafs", representing the basic cases ($|A| = 1$), and it needs $O(n)$ "internal nodes" to divide the work until it reaches the leafs. Given that the longest path has length $O(\log n)$ with a constant cost for each internal node, then the total cost will be $T_\infty = O(\log (n) + k)$ (which is the span). I also can get other measures like the total work $T_1 = O(n + kn)$, and the parallelism $\frac{T_1}{T_\infty} = \frac{n + nk}{k + \log n}$.
Another performance measure of interest is the speedup, which is defined as $\frac{T_1}{T_p}$ (where p is the number of processors used to compute $T_p$).
Finally my question is how do I get $T_p$ (analytically) so I can calculate the speedup? I cannot simply divide $T_1/p$ since in the first levels of the graph/tree I won't be using all the processors.
Is there any more elegant expression for this than simply dividing the height of the tree before and after $\log p$?