Are you using parallelism with .NET? We'd love to know.

Are you using parallelism with .NET? We'd love to know.

  • Comments 27

About six months ago, we posted on this blog to ask for details on if/how you're using Parallel Extensions, and we got a great number of awesome responses... thanks!!  As that blog post has long since faded into distant memory, we're asking again :)

Are you using Parallel Extensions, the parallelism support introduced with .NET 4? e.g. Parallel loops, Tasks, PLINQ, ConcurrentDictionary<>, ConcurrentQueue<>, Lazy<>, BlockingCollection<>, ManualResetEventSlim, ThreadLocal<T>, and so on?  Even if you're using the unsupported .NET 3.5 release of Parallel Extensions, we'd love to hear from you.

Please get in touch by emailing me at stoub at microsoft dot com.  What are you building?  What functionality are you using?  What do you like?  What don't you like?  What features/additions/changes would you like to see in the future?  etc.  Any and all feedback is welcome and encouraged.

Really looking forward to hearing from you!

Thanks,
Stephen

Leave a Comment
  • Please add 1 and 7 and type the answer here:
  • Post
  • olivier and Keith, thanks for taking the time to respond!

  • We're currently using TPL tasks to aggregate a LOT of RSS/ATOM feeds. One question we discussed while developing the current solution was: "is it better to create all the tasks up front and let the library deal with how and when they should execute, or is it better to schedule them in 50 at a time and then scedule new tasks when an existing task completes?" If you have the time, please send the answer to jeh@staff.jubii.dk.

  • I'm interested in parallel algorithms but haven't got a chance to work with the parallel extensions. Would be interesting to know the performance of the primitives provided. It'll be great if simple yet elegant spawn-sync mechanism is provided, similar to Cilk++.

  • Thanks, xman.

  • I've FINALLY managed to set aside some time to learn Parallel Extensions and am excited to get into work tomorrow and refactor some of my long running processses (utilizing ThreadPool) with Parallel.For.  It's going to clean things up quite nicely.

    Thanks!

  • Also, I guess I should clarify that the particular scenario that I am looking forward to refactoring is a domain model pattern that reflects a File and its Records.  I have a list of File objects, and each Record in the Records collection undergoes rigorous rules checking.  The routine takes some time when executed synchronously.  ThreadPool helped my out huge, and I'm looking forward to replacing its usage with Parallel.For() !

  • Aaron, I'm hopeful you'll see very good results.  Please let us know how it goes.

  • I've researched the parallel task library quite a bit while developing a ThreadTree for my company, Vallen Falls.  I believe this ThreadTree would fit in nicely with .NET 4 as it is very fast and a flexable thread manager.  Below is an example of a RayTracer that would be about 40 times faster than the parallel library (From Demo by Luke Hoban).  

    These are the 3 reasons it would be faster than the parallel library.

    1) Uses the ThreadPool

    2) Uses static methods to process threads to avoid memory lookup

    3) Creates a thread for each pixel to avoid memory allocation and GC move delays before continuing the loop.  

    If you are part of the Microsoft's Parallel team and want to borrow the ThreadTree to test it for yourself just let me know and I'll send you the full code.  

    class RenderClass

    {

       public int screenHeight;

       public int screenWidth;

       public bool heightReached;

       public bool widthReached;

       void RenderScene(Scene scene, Int32[] rgb)

       {

           using (ThreadTree tree = new ThreadTree())

           {

               tree.MaxNumberOfWorkingThreads = 50; //I like to use more than the available processors

               RenderThread root = new RenderThread();

               root.ThreadInfo.Data = new ArrayList();

               root.ThreadInfo.Data.Add(rgb); //passing data through ThreadInfo

               root.ThreadInfo.Data.Add(scene);

               root.y = 0;

               root.x = 0;

               root.AcrossThread = True;

               root.tree = tree;

               tree.Add(root);

               tree.RegisterOrRun(root);

               //Wait until all processed (could arrange all threads as childs of root and wait for callback instead)

               while(heightReached == False && widthReached == False)

               {

                  Thread.Sleep(1);

               }

           }

       }

       class RenderThread : ThreadTreeThread

       {

           public int y;

           public int x;

           public bool AcrossThread;

           public ThreadTree tree;

           public bool _heightReached;

           public bool _widthReached;

           public override bool Process(ThreadTreeInfo parentThreadInfo)

           {

               this.ThreadInfo.Data = parentThreadInfo;            

               Int32[] rgb = (Int32[])this.ThreadInfo.Data[0];

               Scene scene = (Scene)this.ThreadInfo.Data[1];

               if(AcrossThread)

               {

                   if(y < screenHeight)

                   {

                       AddThread(y + 1, x, False); //down

                   }

                   else

                   {

                       _heightReached = True;

                   }

                   if(x < screenWidth)

                   {

                       AddThread(y, x + 1, True);  //across

                   }

                   else

                   {

                       _widthReached = True;

                   }

               }

               else

               {

                   if(y < screenHeight)

                   {

                       AddThread(y + 1, x, False); //down

                   }

                   else

                   {

                       _heightReached = True;

                   }

               }

               Ray ray = new Ray(scene.Camera.Pos, GetPoint(x,y,scene.Camera));

               Color color = TraceRay(ray, scene, 0);

               rgb[x+y*screenWidth] = color.ToInt32();            

               return false;

           }

           private void AddThread(int inY, int inX, bool across)

           {

               RenderThread newThread = new RenderThread();

               newThread.y = inY;

               newThread.x = inX;

               newThread.AcrossThread = across;

               tree.Add(newThread);

               tree.RegisterOrRun(newThread);

           }

           public override bool CallBack(ThreadTreeInfo childThreadInfo)

           {

               if(_heightReached)  heightReached;  //in callback to ensure ray is processed before stopping loop

               if(_widthReached)  widthReached;            

               return false;

           }

       }

    }

  • Hi Stephen, we're using TPL for signal processing. Our algorithms are mainly using tasks. The one thing I'd love to see in future releases is more collection types specifically aimed at data parallelism.

  • Hi Tom-

    Thanks for letting us know!  If you wouldn't mind getting in touch by email (stoub at microsoft dot com), I'd be very interested in hearing more about the algorithms you're employing, benefits you've seen from TPL, issues you've faced, and regarding your request, what kinds of collections would be useful to you.

    Thanks!

    Stephen

  • I am using the parallel task library classes for my organization project. I mainly use them to load multiple collections [the ones for UI initialization, customization and of course user data] from the database.

    So far, I'm loving it. It's amazing to see how easy can concurrent programming become.

    Since our host environments are usually 6-8 cores, the performance improvements are amazing.

  • Great to hear, Rhonald.  Thanks for letting us know.

Page 2 of 2 (27 items) 12