Click here to Skip to main content
15,885,908 members
Please Sign up or sign in to vote.
3.00/5 (1 vote)
See more:
Hi, I am using the ThreadPool class to queue application task, but it is using 100% cpu usage. Can we reduce it some how?

Here is the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Threading.Tasks;

namespace InParallel
{
    class Run
    {

        public static void Main(string[] args)
        {
            try
            {
                while (true) // Loop indefinitely
	            {
	                Console.WriteLine("Enter input:"); // Prompt
	                string line = Console.ReadLine(); // Get string from user
	                if (line == "exit") // Check string
	                {
		            break;
	                }
	                int value;
	                if (int.TryParse(line, out value)) // Try to parse the string as an integer
	                {
	                    switch(value)
                        {
                            case 1:
                                Seqential();
                                break;
                            case 2:
                               UsingThreadPool();
                                break;
                            case 3:
                                UsingParaller();
                                break;
                            case 4:
                                UsingThreadPool2();
                                break;
                        }
	                }
	            }



                GC.Collect();
                Console.ReadLine();
               
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        private static void Seqential()
        {
            Console.WriteLine("*************************Started Seqential *********************************");
            Stopwatch watch = Stopwatch.StartNew();

            for (int i = 2; i < 20; i++)
            {
                var result = SumRootN(i);
                // Console.WriteLine("root {0} : {1} ", i, result);
            }

            //WalkTree(myTree);
            // WalkTreeUsingThreadPool(myTree);
            watch.Stop();
            Console.WriteLine("********************End Seqential***************************************");

            Console.WriteLine("Total Time Taken Sequential " + watch.ElapsedMilliseconds.ToString());
        }
        private static void UsingThreadPool()
        {
             ThreadPool.SetMaxThreads(50,50);
             Console.WriteLine("************************Started UsingThreadPool***************************************");
            Stopwatch watch = Stopwatch.StartNew();
           
            for (int i = 2; i < 20; i++)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc),i);
                Console.WriteLine("donefor" + i);
            }

            //WalkTree(myTree);
            // WalkTreeUsingThreadPool(myTree);
            watch.Stop();
            Console.WriteLine("****************************End UsingThreadPool*****************");

            Console.WriteLine("Total Time Taken UsingThreadPool " + watch.ElapsedMilliseconds.ToString());
        }
        private static void UsingParaller()
        {
            Console.WriteLine("*********************Started UsingParaller********************************");
            Stopwatch watch = Stopwatch.StartNew();

            Parallel.For(2, 20, (i) =>
                {
                    var result = SumRootN(i);
                   // Console.WriteLine("root {0} : {1} ", i, result);
                });
            watch.Stop();
            Console.WriteLine("****************************End UsingParaller******************");

            Console.WriteLine("Total Time Taken UsingParaller " + watch.ElapsedMilliseconds.ToString());
        }
        private static void UsingThreadPool2()
        {
            ThreadPool.SetMaxThreads(50, 50);
            Console.WriteLine("************************Started UsingThreadPool***************************************");
            Stopwatch watch = Stopwatch.StartNew();

            //for (int i = 2; i < 20; i++)
            //{
            //    ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), i);
            //    Console.WriteLine("donefor" + i);
            //}

            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc2), 0);
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc2), 1);



            //WalkTree(myTree);
            // WalkTreeUsingThreadPool(myTree);
            watch.Stop();
            Console.WriteLine("****************************End UsingThreadPool*****************");

            Console.WriteLine("Total Time Taken UsingThreadPool " + watch.ElapsedMilliseconds.ToString());
        }
       
        static void ThreadProc(Object stateInfo)
        {
            SumRootN((int)stateInfo);
            // No state object was passed to QueueUserWorkItem, so  
            // stateInfo is null.
           Console.WriteLine("Hello from the thread pool."+Thread.CurrentThread.GetHashCode());
        }

        static void ThreadProc2(Object stateInfo)
        {
            int startcount = (int)stateInfo;
            if (startcount == 0)
            {
                for (int i = 0; i < 10; i++)
                {
                    SumRootN(i);
                }
            }
            else 
            {
                for (int i = 10; i < 20; i++)
                {
                    SumRootN(i);
                }
            }
            
            // No state object was passed to QueueUserWorkItem, so  
            // stateInfo is null.
            Console.WriteLine("Hello from the thread pool." + Thread.CurrentThread.GetHashCode());
        }

        
        public static double SumRootN(int root)
        {
            double result = 0;
            for (int i = 1; i < 10000000; i++)
            {
                result += Math.Exp(Math.Log(i) / root);
            }
            Console.WriteLine("root=" + root+"result="+result);
            return result;
        }

    }

   

   

    
}
Posted
Updated 12-Mar-13 11:22am
v2
Comments
Sergey Alexandrovich Kryukov 12-Mar-13 17:37pm    
Why!?
—SA
Rajeev Jayaram 12-Mar-13 17:42pm    
Did you use any profiler to measure the performance?

1 solution

It has nothing to do with thread pools, only with your thread(s). It depends on what you are doing. In many cases, you really want to use 100% CPU, why not?

As I can see, you are doing some calculations, without any synchronization with anything. And this is want you really may want. After all, do you want to complete your calculation sooner or not? If you do, why wasting some CPU power? Use it all! When you, say, start to do something else, for example, using UI in other processes or the UI thread of your own process, those threads will take their share of the CPU load (depending on number of CPU cores and CPU performance, some delays might disturb you a bit, but you need to pay some price for performance).

You really don't need to take care about using less CPU, you only need to take care about wasting of CPU time. One example where you might waste CPU is polling. To use your system well, you really should avoid polling by all means, because it wastes performance. Please see:
http://en.wikipedia.org/wiki/Polling_%28computer_science%29[^],
http://en.wikipedia.org/wiki/Push_technology[^] (good),
http://en.wikipedia.org/wiki/Pull_technology[^] (pool).

From your sample, I cannot see anything like that, so you probably don't need to worry.

And only if polling or pull is technically unavoidable, you can think about reducing of the CPU load by such a "stupid" thread. One possible alternative technique could be dedicating one of the CPU core to such thread (processor/code affinity, http://en.wikipedia.org/wiki/Processor_affinity[^]), to make the rest of the system more predictable and stable in performance; it can help of you have enough CPUs/cores.

—SA
 
Share this answer
 
Comments
Espen Harlinn 12-Mar-13 17:52pm    
Good points :-D
Sergey Alexandrovich Kryukov 12-Mar-13 18:03pm    
Thank you, Espen.
—SA
sachinDabas 13-Mar-13 2:53am    
Hi,
Thank you for the solution please let me clear why i am worry about 100% CPU utilization.
I want to run this sample application(similar to this) on one of our server which is expose to end customers for there daily activity. usually this server have a CPU utilization of 30-40% now if i run this application on server it will consume the 100% cpu utilization and end user will not able to perform it action and site performance will be down.

I am just started exploring the thread concept Please correct me if i analyses it wrongly
Sergey Alexandrovich Kryukov 13-Mar-13 3:00am    
It's perfectly OK. If you add more threads or processes of the same kind, they will nicely share CPU load, according to priorities and other factors. Again, follow the simple idea: you cannot be wrong if you are not wasting the CPU. Compare with some pure-UI application, like an editor: when you don't touch keyboard/mouse, it should go to wait state and spend zero CPU. If this is not so, this is a waste. But you are doing calculations all the time. You are not wasting anything, and really want your 100% CPU.

You can of course load the system too much with too many processes, so it can become purely responsive, but I think everyone understands that.

I hope you get the idea and can accept my answer formally (green button) — thanks.
—SA
sachinDabas 13-Mar-13 3:42am    
Hi sergey, I appreciate your solution.
PFB the below steps i followed to test it.
I run one simple asp.net web application it works fine but when i turned on this Threadpool application my web application performance is degrading.
Did i am doing a right analysis? it is explain my problem?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900