C#Parallel和Task太慢了

时间:2018-04-04 20:32:47

标签: c# parallel-processing

我尝试使用并行或任务计划或其他任何方式在4秒内完成工作时遇到问题。脚本很简单,它会尝试一次处理100次并等待结果。我的电脑是E5-2603 Xeon处理器(4核,4线程,1.80GHz),16GB,处理100个任务需要永远。

我该怎样做才能加快这个过程?

测试脚本

static void Main(string[] args)
        {
            //Monitor performance
            Stopwatch totalTime = new Stopwatch();


            //Test case # 1
            totalTime.Start();
            TaskTechnique();
            totalTime.Stop();
            Console.WriteLine("TaskTechnique total time: " + totalTime.Elapsed.TotalSeconds);
            Console.WriteLine("--------------------------------------");

            //Test case #2
            totalTime.Reset();
            totalTime.Start();
            ParalelelTechnique();
            totalTime.Stop();
            Console.WriteLine("ParalelelTechnique total time: " + totalTime.Elapsed.TotalSeconds);
            Console.WriteLine("--------------------------------------");

        }

When Task Class Definition Namespace: System.Threading.Tasks

处理100个小任务需要21秒。代码在

之下
    /// <summary>
    /// Using task to process all tasks
    /// </summary>
    private static void TaskTechnique()
    {

        //Test case 1 process all 100 tasks at once
        List<Task<string>> tasks = new List<Task<string>>();
        for (int i = 0; i < 100; i++)
        {
            tasks.Add(
                    Task.Factory.StartNew
                    (
                            () =>
                            {
                                return MrDelay(i);
                            }
                    )
                );
        }

        Task.WaitAll(tasks.ToArray());//Wait until finished 
    }

And when I used Parallel,处理需要33秒。

  /// <summary>
        /// Using Paralelel to process 100 times
        /// </summary>
        private static void ParalelelTechnique()
        {
            //Monitor performance
            Stopwatch startTime = new Stopwatch();
            //Test case 2 using parallel
            startTime.Restart();
            int maxTask = 100;
            var result = Parallel.For
                (
                1, 101,
                new ParallelOptions { MaxDegreeOfParallelism = maxTask },
                (i, state) =>
                {
                    Console.WriteLine("Beginning iteration {0} at ", i, DateTime.Now.ToLocalTime());
                    string longTaskResult = MrDelay(i);
                    Console.WriteLine("Completed iteration {0} result at : {1}", i, longTaskResult);
                }
                );
            startTime.Stop();
            Console.WriteLine("test case 2: " + startTime.Elapsed.TotalSeconds);
        }

延迟流程代码。

/// <summary>
    /// Just to slow down the test to 3 seconds before return the data back
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    private static string MrDelay(int id)
    {
        //Delay 3 seconds then return the result
        System.Threading.Thread.Sleep(3000);
        return "ok request id: " + id.ToString() + "  processed time: " + DateTime.Now.ToLocalTime();
    }

2 个答案:

答案 0 :(得分:0)

对于群发服务代码,您必须首先回答问题:应该最大化什么?

例如,使用“任务”意图&#34;最大吞吐量&#34;。这意味着您的任务可能会经常中断等待某些事情,因此让CPU核心切换到另一项任务,以免浪费时间。每个任务的平均执行时间相对较长,但每个给定时间处理的平均任务量却在飞速发展。

此处的另一个案例是&#34;最大CPU刻录&#34;。例如,工作人员就像处理音频/视频流,像加密等大数学工厂一样。这样,最有效的方法是每个备用CPU核心有一个线程/任务,而不是更多(因为切换到另一个线程会花费额外的CPU费用)。与前面的示例相反,这里我们在给定时间内处理的平均任务量相对较低。但由于最小的中断,平均执行时间尽可能短。

当然,在实际操作中,你有一些介于最大值之间的东西。当然,你必须更多地了解什么可以确定你的CPU(内核调用,缓存污染,错误共享,数据竞争等等)。你可以从&#34; No Bugs Hare&#34;:http://ithare.com/using-parallel-algorithm-without-a-clue-90x-performance-loss-instead-of-8x-gain/

中的精彩文章开始

答案 1 :(得分:-3)

感谢提示,我通过使用多线程提出了另一种解决方案。此应用程序将用于桌面应用程序,因此这是可以接受的。我能够使用线程在3秒内处理200个任务以及更多任务,而不是30秒以上的100个任务。

  static void Main(string[] args)
    {
        #region MyRegion
        for (int i = 0; i < 200; i++)
        {
            //Create thread
            Thread thread = new Thread(() => DoBigJobThread(i));
            thread.Start();
        }
        #endregion
        //Slow  down to show screen
        System.Threading.Thread.Sleep(3000000);
    }

    static void DoBigJobThread(int id)
    {
        Console.WriteLine(MrDelaySimple(id));
    }

    private static string MrDelaySimple(int id)
    {
        //Delay 3 seconds
        System.Threading.Thread.Sleep(3000);
        return "ok request id: " + id.ToString() + "  processed time: " + DateTime.Now.ToLocalTime();
    }