多线程比顺序线程花费更多的时间

时间:2019-11-02 07:09:39

标签: c# multithreading

我是C#的新手 我正在生成随机数,并将其保存到大小为100万的整数数组中,然后使用单线程在数组中搜索用户输入数字及其出现的位置,然后使用5个线程对其进行搜索。我的处理器有4个核心。 问题:多线程比顺序处理花费更多的时间,我只是想不出为什么要感谢任何帮助。 这是代码。

namespace LAB_2
{
    class Program
    {
        static int[] arr = new int[1000000];
        static int counter = 0, c1 = 0, c2 = 0, c3 = 0, c4 = 0,c5=0;
        static int x = 0;

#if DEBUG
        static void Main(string[] args)
        {

            try
            {
                //Take input
                generate();
                Console.WriteLine("Enter number to search for its occurances");
                x = Console.Read();

                //Multithreaded search
                Stopwatch stopwatch2 = Stopwatch.StartNew();
                multithreaded_search();

                stopwatch2.Stop();
                Console.WriteLine("Multithreaded search");
                Console.WriteLine("Total milliseconds with multiple threads = " + stopwatch2.ElapsedMilliseconds);

                //search without multithreading
                Stopwatch stopwatch = Stopwatch.StartNew();
                search();
                stopwatch.Stop();
                Console.WriteLine("Total milliseconds without multiple threads = " + stopwatch.ElapsedMilliseconds);

            }
            finally
            {
                Console.WriteLine("Press enter to close...");
                Console.ReadLine();
            }
#endif

        }
        public static void generate() //Populate the array
        {
            Random rnd = new Random();

            for (int i = 0; i < 1000000; i++)
            {
                arr[i] = rnd.Next(1, 500000);
            }

        }
        public static void search() //single threaded/Normal searching
        {

            int counter = 0;

            for (int i = 0; i < 1000000; i++)
            {
                if (x == arr[i])
                {
                    counter++;
                }
            }
            Console.WriteLine("Number of occurances " + counter);
        }

        public static void multithreaded_search()
        {


            Task thr1 = Task.Factory.StartNew(() => doStuff(0, 200000, "c1"));
            Task thr2 = Task.Factory.StartNew(() => doStuff(200001, 400000, "c2"));
            Task thr3 = Task.Factory.StartNew(() => doStuff(400001, 600000, "c3"));
            Task thr4 = Task.Factory.StartNew(() => doStuff(600001, 800000, "c4"));
            Task thr5 = Task.Factory.StartNew(() => doStuff(800001, 1000000, "c5"));

 //IF I don't use WaitAll then the search is 
 //faster than sequential, but gets compromised
            Task.WaitAll(thr1, thr2, thr3, thr4, thr5);            
            counter = c1 + c2 + c3 + c4 + c5;
            Console.WriteLine("Multithreaded search");
            Console.WriteLine("Number of occurances " + counter);
        }
        static void doStuff(int stime, int etime, String c)
        {
            for (int i = stime; i < etime; i++)
            {
                if (x == arr[i])
                {
                    switch (c)
                    {
                        case "c1":
                            c1++;
                            break;
                        case "c2":
                            c2++;
                            break;
                        case "c3":
                            c3++;
                            break;
                        case "c4":
                            c4++;
                            break;
                        case "c5":
                            c5++;
                            break;
                    };
                }
                Thread.Yield();
            }
        }

    }

}

1 个答案:

答案 0 :(得分:0)

首先,在doStuff中,您要做的工作要比搜索更多。虽然它不太可能产生明显的效果,但您永远不会知道。

第二,Thread.Yield是执行任务的杀手。当您认为锁可能太昂贵时,该方法旨在用于极少数情况下,例如旋转。在这里,这只是代码的刹车,导致OS调度程序完成更多工作,甚至可能在当前内核上进行上下文切换,从而使缓存无效。

最后,您的数据和计算量很小。现代的CPU会立即枚举这样的数组,它的很大一部分甚至全部都可以放入缓存中。并发处理有其开销。

我推荐Benchmark.NET