Dot Net Perls

ThreadPool Throughput Improvement - C#

by Sam Allen

Problem

You are using ThreadPool and want to improve performance and throughput. The SetMinThreads method allows you to alleviate some bottlenecks with ThreadPool. Estimate a good setting for minimum threads.

Solution: ThreadPool in C#

First we need to see why we need a minimum thread setting. The reason in some cases is that Microsoft has some safeguards in their thread code that interfere.

MSDN on ThreadPool.SetMinThreads: This method tells Windows to keep a specific number of idle threads to anticipate new requests.

MSDN on thread intervals: "The thread pool does not immediately begin creating new idle threads" when there are no existing threads remaining for work items. It does this to avoid excessive allocated memory. [ThreadPool.SetMinThreads Method (System.Threading) - MSDN]

The interval MSDN states that the ThreadPool uses in the .NET runtime on Windows is half a second. In the software world, half a second is a long time.

Task: changing the minimum number of threads

There are two methods that are most important here. The first is ThreadPool.GetMinThreads, which accepts two out parameters. It is useful to get these values for diagnostics or for changing the actual values. [ThreadPool.GetMinThreads Method (System.Threading) - MSDN]

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        // A
        // Get the numbers of minimum threads
        int w;
        int c;
        ThreadPool.GetMinThreads(out w, out c);

        // B
        // Write the numbers of minimum threads
        Console.WriteLine("{0}, {1}",
            w,
            c);

        // C
        // Change the numbers of minimum threads
        ThreadPool.SetMinThreads(20,
            c);
        // 2, 2
    }
}

Part B above will display 2, 2 on a dual core machine, but can display 4 on a quad core computer. Remember that multicore computing is new and changing rapidly, so these are subject to changes.

Information: benchmark of setting minimum threads

It is advantageous for you to use the SetMinThreads method in some cases. MSDN states that if your app has "bursts of activity" in which many threads are used at once, SetMinThreads improves performance.

This benchmark runs tests of bursts of activity with 50 work items each time. It changes the minimum thread setting from 2 to 40.

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        // 1
        // Loop through number of min threads we use
        for (int c = 2; c <= 40; c++)
        {
            // 2
            // Use AutoResetEvent for thread management
            AutoResetEvent[] arr = new AutoResetEvent[50];
            for (int i = 0; i < arr.Length; ++i)
            {
                arr[i] = new AutoResetEvent(false);
            }

            // 3
            // Set the number of minimum threads
            ThreadPool.SetMinThreads(c, 4);

            // 4
            // Get current time
            long t1 = Environment.TickCount;

            // 5
            // Enqueue 50 work items that run the code in this delegate function
            for (int i = 0; i < arr.Length; i++)
            {
                ThreadPool.QueueUserWorkItem(delegate(object o)
                {
                    Thread.Sleep(100);
                    arr[(int)o].Set(); // Signals completion

                }, i);
            }

            // 6
            // Wait for all tasks to complete
            WaitHandle.WaitAll(arr);

            // 7
            // Write benchmark results
            long t2 = Environment.TickCount;
            Console.WriteLine("{0},{1}",
                c,
                t2 - t1);
        }
    }
}

What I found is that increasing the number of minimum threads improved performance dramatically when it reached 5 and continued improving until 13.

Note that this benchmark is highly dependent on your machine's configuration. If you are reading this in 2015, you will need new benchmarks.

Summary: using SetMinThreads with ThreadPool

We saw how changing the number of minimum threads in the ThreadPool can improve performance on a dual core machine. This is most useful for programs with bursts of activity involving many threads.

Be careful with SetMinThreads, however, because if you keep too many threads, your program's performance may suffer due to increased memory usage.

The technical details for this article were contributed by Neil Justice. Dot Net Perls thanks him for the contribution of this interesting throughput optimization.

ThreadPool in C# has several optimizations for throughput and asynchronous programming, and you can improve upon the defaults. [C# - ThreadPool and Progress UI - dotnetperls.com]

Dot Net Perls
About
Sitemap
Language Features
Struct Examples and Tricks
Run Commands With Process.Start
Enum Tips and Examples
ThreadPool and Progress UI
DllImport, dllexport Interop
New
StartsWith String Examples
GZIP Accept-Encoding Request
© 2008 Sam Allen. All rights reserved.