none
question about LimitedConcurrencyTaskScheduler

    Question

  • Folks who wrote the book Parallel Programming With Microsoft.Net:

    I'm using LimitedConcurrencyTaskScheduler via ParallelOptions.TaskScheduler and Parallel.For/ForEach.  If I don't set the ParallelOptions .MaxDegreeOfParallelism, am I guaranteed to get X parallel executions where X =maxDegreeOfParallelism set in LimitedConcurrencyTaskScheduler constructor?  Is it possible that any part of the code involved in this would use less than X threads?  I'm looking for a solution to use Parallel.For/ForEach and guarantee that maxDegreeOfParallelism threads are used - no more, no less ( unless of course most of the tasks have been completed and there are less than X tasks left to process).

    Thanks!

    Friday, March 11, 2011 6:36 PM

Answers

  • The sample code you referenced would create a single partition per "work item".  If you combine this with the LimitedConcurrencyTaskScheduler (or just set MaxDegreeOfParallelism), you should get each item being handled on one thread, one at a time.  This is probably fine if the amount of work per task is very large.

     

    As for the difference between using LCTS and the default with MaxDegreeOfParallelism set - there should be very little difference here.  I don't remember all of the implementation detials of the LCTS, but it does schedule out on the ThreadPool, so the end result should be very, very similar.

     

     


    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 sfun28 Friday, March 11, 2011 8:00 PM
    Friday, March 11, 2011 7:57 PM
    Moderator

All replies

  • The LimitedConcurrencyTaskScheduler will almost do what you want, but not completely.

     

    This statement of yours shows the basic issue here:

    "unless of course most of the tasks have been completed and there are less than X tasks left to process"

     

    The main reason you might have less than X threads running is that Parallel.For and Parallel.ForEach use a Partitioner internally to partition out tasks.  They don't execute each task independently and schedule each task to the TaskScheduler one at a time, but rather partition the "tasks" into chunks of tasks, and then schedule each "chunk" to the partitioner.

     

    As a result, you could easily have many tasks left to process, but only one or two "partitions", which would mean you'd only be using one or two threads at that point.  You could specify a custom partitioner that partitioned out every task into its own partition, and then you'd get the behavior you described.  However, this is generally a bad idea.  If the "work" a task is performing is "small", partitioning into groups dramatically reduces the overhead in the system, which significantly improves the overall performance.



    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Friday, March 11, 2011 7:08 PM
    Moderator
  • Hi Reed,

    Thanks so much for responding!  Unfortunately the work my task is performing is "large" - its long-running.  I've found that from a performance POV, its best to have one thread per CPU core.  I'm trying to find a way to accomplish that using Parallel.ForEach.  Does the code sample here accomplish this?  If not, could you point me in the right direction?
    http://msdn.microsoft.com/en-us/library/dd381768.aspx

    So is the solution to use the custom partitioner alongside the LimitedConcurrencyTaskScheduler? Or could I use the default TaskScheduler at that point and just set MaxDegreeOfParallelism?  What would be the difference?

     

    Friday, March 11, 2011 7:21 PM
  • The sample code you referenced would create a single partition per "work item".  If you combine this with the LimitedConcurrencyTaskScheduler (or just set MaxDegreeOfParallelism), you should get each item being handled on one thread, one at a time.  This is probably fine if the amount of work per task is very large.

     

    As for the difference between using LCTS and the default with MaxDegreeOfParallelism set - there should be very little difference here.  I don't remember all of the implementation detials of the LCTS, but it does schedule out on the ThreadPool, so the end result should be very, very similar.

     

     


    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 sfun28 Friday, March 11, 2011 8:00 PM
    Friday, March 11, 2011 7:57 PM
    Moderator
  • Reed - thanks so much!
    Friday, March 11, 2011 8:01 PM