There should be a way to prioritize control flow tasks in SSIS. When multiple tasks are available for execution at the same time there does not appear to be any way to influence which tasks will begin executing first. If there are more tasks than available worker threads then each thread picks a task to execute, apparently at random, and the other tasks have to wait for a thread to complete before they can begin executing. So far there have been two scenarios identified where this can lead to some highly inefficient flow patterns.
Scenario 1: Multiple tasks running in parallel, having significant differences in execution times.
Assume 10 tasks with no dependencies and 4 worker threads. Tasks A&B each require 10 minutes, the remaining 8 tasks each require 2 minutes. In the best case scenario the first two threads will pick tasks A&B to start executing, the remaining two threads will select two of the remaining tasks (C&D). Two minutes later tasks C&D will be complete and those two threads will start on E&F, etc. End result is that the entire process takes 10 minutes with two threads sitting idle for the final two minutes. Total idle time is 4 minutes. The worst case scenario is that tasks A&B are the lasts tasks to be picked, in which case they do not get to start until 4 minutes into the process and then they take an addition 10 minutes to run. End result is that the same process takes 14 minutes with two threads sitting idle for ten minutes. Total idle time is 20 minutes.
Scenario 2: Multiple tasks running in parallel having varying levels of dependencies.
This scenario is much more difficult to describe. It involves having multiple branches of sequential tasks. In some ways you could look at each branch as being a single task from scenario 1. The issue here though is not how long any one tasks takes to complete but how many other tasks have to wait for it to finish before they can start processing. In an optimal run (assumes all tasks have similar run times) the task with the most dependencies should be executed before the tasks with fewer dependencies. What I have often observed however is tasks with no dependencies being executed before tasks with a great number of dependencies. This results in threads sitting idle waiting for a single task to complete so that they can move on to process its dependencies.