Friday, October 2, 2009

To Spin or not to Spin and a little PFX

With the advent of multi core computers more developers are getting into spinning threads. I won’t go into how to spin a thread. But it’s getting easier, .NET4 will bring parallel extensions to the framework so you can do parallel “for” loops. Checkout http://blogs.msdn.com/pfxteam/ for more info.

You may think running something on more than one thread won’t be any faster, you will be very surprised with the results.

But just because you can spin a thread it does not mean you should.

A good rule to follow is

Don’t spin if your code is going to be executed by a web service or web site

Web sites / web services by their nature are multi threaded. IIS will decide how many threads to spin to service your content. If you spin extra threads you may add load to the server.

Do spin threads if your code is going to be executed on a desktop machine

Generally your program is not going to have multiple instances that are all very busy doing work for multiple users. So it’s good to spin threads. But do consider the effect of nesting:
If we are going to spin more than one thread for this loop :

public static void DoSubWork()
{
  // We could spin 4 threads for this
  for (int i = 0; i < 5000; i++)
  {
  }
}

And we decide to spin more threads for this loop :

public static void DoLotsOfWork()
{
  // We could spin 4 threads for this
  for (int i = 0; i < 1000000; i++)
  {
  }
}

Then we make DoLotsOfWork() call DoSubWork() we are going to be spinning lots more threads. That’s where PFX comes in. PFX will manage the thread pool count so that is does not exceed a fixed limit. So with PFX your code would look like :

public static void DoLotsOfWork()
{
  Parallel.For(1, 1000000, i; =>
  {
    DoSubWork();
  });
}

public static void DoSubWork()
{
  Parallel.For(1, 1000000, i =>
  {
  });
}

If you call DoLotsOfWork() you will see that it will not spin more than 4 threads. You can view by debugging the code and viewing the thread window (Debug – Windows – Threads) or (CTRL+D,T)

This is my thread list. (just the ones that are doing the looping)

840 ThreadExample.Program.DoLotsOfWork
1880 ThreadExample.Program.DoLotsOfWork.AnonymousMethod
6724 ThreadExample.Program.DoLotsOfWork.AnonymousMethod
4332 ThreadExample.Program.DoSubWork.AnonymousMethod
6176 ThreadExample.Program.DoSubWork.AnonymousMethod

I do think one limitation of PFX (or at least with the CTP) is that you cannot choose how many threads. It will use core count * 2. I can understand the reason for this but if you are spinning more than one thread to download lots of images from a website then you may want to base the number of threads that you spin upon bandwidth rather than CPU resources. (I will have to check .NET4 to see if this has changed)

No comments:

Post a Comment