C#附加线程降低了应用程序的效率

时间:2016-05-24 03:53:19

标签: c# multithreading

我想强调测试我的新cpu。我在大约2分钟内做到了这一点。

当我添加更多线程时,它的效率会急剧下降。这些是结果:(请注意我将taskmanager中的Priority设置为High)

1个主题:在1个主题上一分钟之后,你得到了数字/素数680263811

2个主题:在2个主题上一分钟之后,你得到了数字/素数360252913

4个主题:在4个主题上一分钟之后,你得到了数字/素数216150449

代码存在问题,我只是将其作为测试。请不要抨击我写得太可怕了......我有点糟糕的一天

    static void Main(string[] args)
    {
        Console.Write("Stress test, how many OS threads?: ");
        int thr = int.Parse(Console.ReadLine());
        Thread[] t = new Thread[thr];
        Stopwatch s = new Stopwatch();
        s.Start();
        UInt64 it = 0;
        UInt64 prime = 0;
        for (int i = 0; i < thr; i++)
        {

            t[i] = new Thread(delegate() 
            {

                while (s.Elapsed.TotalMinutes < 1)
                {
                    it++;
                    if (it % 2 != 0)// im 100% sure that x % 2 does not give primes, but it uses up the cpu, so idc
                    {
                        prime = it;
                    }
                }
                Console.WriteLine("After one minute on " + t.Length + " thread(s), you got to the number/prime " + prime.ToString());//idc if this prints 100 times, this is just a test

            });
            t[i].Start();



        }

        Console.ReadLine();

    }

问题:有人可以解释这些意外结果吗?

2 个答案:

答案 0 :(得分:3)

你的线程在没有任何同步的情况下递增it,所以你会得到像这样的奇怪结果。更糟糕的是,您还分配 prime而没有任何同步。

  • 主题1:从0读取it,然后由于某种原因被操作系统取消安排
  • 主题2:从0读取it,然后递增到1
  • 主题2:确实有效,将1分配给prime

  • ...线程2重复一段时间。线程2现在最多为7,即将检查if (it % 2 != 0)

  • 主题1:重新获得CPU

  • 主题1:将it增加到1
  • 主题2:将1分配给prime --- wat?

当你到达it的高半位的位置正在发生变化时,可能性变得更糟,因为64位读写也不是原子的,尽管这些数字比问题,在运行更长时间后,可能会发生变化......考虑

过了一段时间it = 0x00000000_FFFFFFFF

  • 主题1读取it(两个单词)
  • 主题2读取较高的单词0x0000000_????????
  • 主题1计算it + 1 0x00000001_00000000
  • 主题1写it(两半)
  • 线程2读取低位字(并将其与已经读过的一半放在一起)0x00000000_00000000

当线程1递增到4294967296时,线程2设法读取0。

答案 1 :(得分:-3)

您应该应用关键字volatile来变量和填充。