none
Adjust relative priority of several long running Tasks using TPL

    Question

  • Does anybody have some comments on the following problem:

    Within an application two different tasks are both computing a large number of points for two different charts. (Within the Tasks, Parallel.For is used to compute the points.) The computation takes several minutes to complete.

    In the GUI the charts are updated accordingly based on the progress of this calculation. The problem is, that the user might want to see the results for one chart faster than that for the other chart. Hence, I would like to use more CPU time for the corresponding task (i.e. have a ratio of 3 computed points within this primary task and just one in the secondary task). It's ok to slow down the secondary task than. How could this be achieved? Also, the user might select the other chart while the computation is running. If this happens, I would like to switch the priority, making the other task using more CPU time.

    I did some tests using SpinWait in the tasks. This seems to work but I wonder if there is a better solution for this type of problem.

    Friday, March 18, 2011 10:07 AM

Answers

  • A better solution could be to use a custom TaskScheduler, and use this in the ParallelOptions to control each of the Parallel.For loops.

     

    For details on how this could be done, see the MSDN sample for a TaskScheduler that limits the degree of concurrency: http://msdn.microsoft.com/en-us/library/ee789351.aspx

     

    I could see two approaches - a single (shared) scheduler could be used, which could just schedule 3 items for each 1 in the "inactive" version.  Alternatively, you could just limit the degree of concurrency in each "pool" to get the priority you require.


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    • Marked as answer by nfc036 Tuesday, March 22, 2011 11:32 AM
    Friday, March 18, 2011 6:21 PM

All replies

  • A better solution could be to use a custom TaskScheduler, and use this in the ParallelOptions to control each of the Parallel.For loops.

     

    For details on how this could be done, see the MSDN sample for a TaskScheduler that limits the degree of concurrency: http://msdn.microsoft.com/en-us/library/ee789351.aspx

     

    I could see two approaches - a single (shared) scheduler could be used, which could just schedule 3 items for each 1 in the "inactive" version.  Alternatively, you could just limit the degree of concurrency in each "pool" to get the priority you require.


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    • Marked as answer by nfc036 Tuesday, March 22, 2011 11:32 AM
    Friday, March 18, 2011 6:21 PM
  • Thank you for your answer, Reed.

    Regarding the "degree of concurrency in each pool" I wonder whether this is possible at all on single or dual core machines? I know that we are talking about parallelization, but there are still single core CPUs out there... *snip* I will check this. From the link above it seems, that the maximum degree of parallelization is not neccessarily limited by the number of cores, right? But than, how could I switch the priority from one "pool" to the other when the calculation is already running?

    I have not yet any experience with custom TaskSchedulers. Am I right that using a TaskScheduler to get the given ratio would mean not to use Parallel.For but create individual tasks for every single (or small groups) of points?

    Have a nice weekend!

    Friday, March 18, 2011 8:16 PM
  • Thank you for your answer, Reed.

    Regarding the "degree of concurrency in each pool" I wonder whether this is possible at all on single or dual core machines? I know that we are talking about parallelization, but there are still single core CPUs out there... *snip* I will check this. From the link above it seems, that the maximum degree of parallelization is not neccessarily limited by the number of cores, right? But than, how could I switch the priority from one "pool" to the other when the calculation is already running?

    I have not yet any experience with custom TaskSchedulers. Am I right that using a TaskScheduler to get the given ratio would mean not to use Parallel.For but create individual tasks for every single (or small groups) of points?

    Have a nice weekend!

    Nope - When you use Parallel.For, you can specify a TaskScheduler (that gets used internally) in the ParallelOptions.  For details, see this overload: http://msdn.microsoft.com/en-us/library/dd781401.aspx

     

    Single core and dual core CPUs still tend to schedule more tasks than cores, and the OS does some level of switching between them.  I would design your API around your most common use case, though, and let the system break up and schedule the tasks appropriately.

     


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Sunday, March 20, 2011 9:25 PM
  • Thank you for pointing me into the right direction. Based on the QueuedTaskScheduler from ParallelExtensionsExtras I was able to add a "Weight" per Queue. This weight can than be used to schedule tasks in an appropriate ratio. And - it's also possible to change these weights dynamically when needed.
    Tuesday, March 22, 2011 11:31 AM