C#中的多个并行任务不会缩短计算时间

问题描述 投票:0回答:3

我有一个复杂的数学问题要解决,因此我决定并行进行一些独立的计算以缩短计算时间。在许多CAE程序中,例如ANSYS或SolidWorks,可以为此设置多个内核。

我创建了一个简单的Windows Form示例来说明我的问题。在此,功能CalculateStuff()从功率的A Sample次的1.2类中提高max。对于2个任务,它是max / 2次;对于4个任务,它是max / 4次。

我只计算了一个CalculateStuff()功能或四个重复的代码(CalculateStuff1(), ...2(), ...3(), ...4()-每个任务一个)的运算时间,它们使用相同的代码。我不确定,对于每个任务使用相同的功能是否有意义(无论如何,Math.Pow相同)。我也尝试启用或禁用ProgressBar。

该表表示所有12种情况的操作时间(秒)。我希望2和4个任务的速度会快2到4倍,但在某些情况下4个任务甚至比1还要差。我的计算机有2个处理器,每个10核。根据“调试”窗口,CPU使用率随着任务的增加而增加。我在这里的代码有什么问题,还是我误会了某些东西?为什么多项任务不能改善手术时间?

Table of results

        private readonly ulong max = 400000000ul;

        // Sample class
        private class Sample
        {
            public double A { get; set; } = 1.0;
        }

        // Clear WinForm elements
        private void Clear()
        {
            PBar1.Value = PBar2.Value = PBar3.Value = PBar4.Value = 0;
            TextBox.Text = "";
        }

        // Button that launches 1 task
        private async void BThr1_Click(object sender, EventArgs e)
        {
            Clear();
            DateTime start = DateTime.Now;

            Sample sample = new Sample();

            await Task.Delay(100);
            Task t = Task.Run(() => CalculateStuff(sample, PBar1, max));
            await t;

            TextBox.Text = (DateTime.Now - start).ToString(@"hh\:mm\:ss");

            t.Dispose();
        }

        // Button that launches 2 tasks
        private async void BThr2_Click(object sender, EventArgs e)
        {
            Clear();
            DateTime start = DateTime.Now;

            Sample sample1 = new Sample();
            Sample sample2 = new Sample();

            await Task.Delay(100);
            Task t1 = Task.Run(() => CalculateStuff(sample1, PBar1, max / 2));
            Task t2 = Task.Run(() => CalculateStuff(sample2, PBar2, max / 2));
            await t1; await t2;

            TextBox.Text = (DateTime.Now - start).ToString(@"hh\:mm\:ss");

            t1.Dispose(); t2.Dispose();
        }

        // Button that launches 4 tasks
        private async void BThr4_Click(object sender, EventArgs e)
        {
            Clear();
            DateTime start = DateTime.Now;

            Sample sample1 = new Sample();
            Sample sample2 = new Sample();
            Sample sample3 = new Sample();
            Sample sample4 = new Sample();

            await Task.Delay(100);
            Task t1 = Task.Run(() => CalculateStuff(sample1, PBar1, max / 4));
            Task t2 = Task.Run(() => CalculateStuff(sample2, PBar2, max / 4));
            Task t3 = Task.Run(() => CalculateStuff(sample3, PBar3, max / 4));
            Task t4 = Task.Run(() => CalculateStuff(sample4, PBar4, max / 4));
            await t1; await t2; await t3; await t4;

            TextBox.Text = (DateTime.Now - start).ToString(@"hh\:mm\:ss");

            t1.Dispose(); t2.Dispose(); t3.Dispose(); t4.Dispose();
        }

        // Calculate some math stuff
        private static void CalculateStuff(Sample s, ProgressBar pb, ulong max)
        {
            ulong c = max / (ulong)pb.Maximum;

            for (ulong i = 1; i <= max; i++)
            {
                s.A = Math.Pow(s.A, 1.2);

                if (i % c == 0)
                    pb.Invoke(new Action(() => pb.Value = (int)(i / c)));
            }
        }
c# multithreading winforms task
3个回答
5
投票

任务不是线程。 “异步”并不意味着“同时”。


2
投票

有很多可能的原因,您可能看不到期望的性能提升,包括目前机器内核正在使用的其他东西。运行此精简版本的代码,并行运行时,我可以看到明显的改进:


0
投票

不幸的是,我无法给您一个原因,除了可能与状态机魔术有关的事情之外,但这显着提高了性能:

© www.soinside.com 2019 - 2024. All rights reserved.