marocano1
marocano1

Reputation: 89

High CPU usage in C# multi-threaded code

I don't have much knowledge in writing good multi-threaded code. I have just recently started working on a project where it is necessary. I have written the following code, which works as I want it to, however, the CPU usage is very high. I am assuming it is due to how I am using the threads. If anyone could point out the flaw in the below code and let me know how to fix it so the CPU usage is not so high, I would greatly appreciate it.

var numberOfMinutes = Convert.ToInt32(ConfigurationManager.AppSettings["NumberOfMinutesToRun"]);
var traversals = DbLayer.GetTraversals().ToList();
var numberOfThreads = Convert.ToInt32(ConfigurationManager.AppSettings["NumberOfThreads"]);
var threads = new List<Thread>(numberOfThreads);
var counter = 1;
var s = new Stopwatch();
s.Start();
var sync = new object();
while (s.Elapsed < TimeSpan.FromMinutes(numberOfMinutes))
{
    for (var i = 0; i < (numberOfThreads - threads.Count); i++)
    {
        var counter1 = counter; // due to closure.
        var traversal = traversals.FirstOrDefault(t => t.Id == counter1);
        var threadStart = new ThreadStart(new CallHelper(traversal).Migrate);
        var i1 = i;
        threadStart += () =>
                       {
                            threads.RemoveAt(i1);
                       };
        threads.Insert(i, new Thread(threadStart) {IsBackground = true});
        threads[i].Start();
        lock (sync)
        {
            counter++;
            if (counter > 6)
            {
                counter = 1;
            }
        }
    }
}
s.Stop();

I updated the code to show, what I hope, is required to help me. The traversals collection contains only 6 items. The counter is there to ensure that the threads rotate through each of the 6 items in the traversals collection. The CallHelper class is just performing a very long running task on each traversal. The application is designed to perform the long running task on 6 different objects using a configurable amount of threads for a configurable amount of time. Hopefully I have filled in enough of the blanks.

Upvotes: 3

Views: 3546

Answers (1)

Taylor Kidd
Taylor Kidd

Reputation: 1511

There are a variety of resources available on line for writing good and efficient multi-threaded code. "Good" generally refers to working and robust code. For efficient code, use embedded resources.

I only scanned your code but can see a variety of issues and can offer suggestions.

  1. Use a thread pool. Building and tearing down threads is very expensive.
  2. Repeat the loop as infrequently as possible (as mentioned above).
  3. Use sleeps and not busy loops when you need to delay.
  4. Use non-trivial code to test efficiency. If you are testing against trivial code, your utilization will be dominated by program (not just thread) setup and tear down, something that is very expensive and will dominate the cpu utilization.
  5. Measure the utilization of the code you are interested in and exclude that which you are not, such as application setup and tear down.

Upvotes: 1

Related Questions