Add sampling and clean up code for modeling.
Clean up the command-line arguments and the associated parse functions.
Reorganize the code for the runtime modeling.
Use the first tier when computing the size of common data dependencies.
Cut down the number of calls to expensive functions.
We don't have to determine the optimal tiers per task since that can easily derived from
the total tiers and the optimal task size.
Find the optimal values by iterating over different task sizes instead of
resources. This cuts down the number of iterations since we can skip the cases
where number of resources is greater than number of tasks.
Add control for tuning the granularity at which the optimal values are
estimated. This allows us to navigate the trade-off between model accuracy and
its overhead.