为什么我的并行 for 循环比 for 慢得多?

Why my parallel for loop is much slower than for?

我尝试用并行循环更改我的 for 循环,但速度太慢了,而不是在一分钟内完成循环,而是在 30 分钟内完成。循环所做的是从一个数字开始,检查它是奇数还是偶数。如果它是奇数,它乘以 3 并加 1。如果它是偶数,它除以 2。继续重复直到数字达到 4,并且有一个循环,每次重复 100 万次,数字增加 1。我提到的最后一个循环是我尝试更改为并行循环的循环。这是普通 for 循环的代码:

        static void Main(string[] args)
        {
            
            BigInteger currenthighest =new BigInteger(Math.Pow(2,68));
            BigInteger currentValue;
            Console.WriteLine(currenthighest);
            Console.ReadKey();
            for (int i = 1; i > -1; i++)
            {
               
                for (int z = 0; z != 1000000; z++)
                 {
                     currentValue = currenthighest;
                     while (currentValue != 4)
                     {
                         if (currentValue % 2 == 0)
                         {
                             currentValue = currentValue / 2;
                         }
                         else
                         {
                             currentValue = (currentValue * 3) + 1;
                         }
                     }
                     currenthighest++;
                 }    
                Console.WriteLine(" {0} times done", i * 1000000);
            } 
        }

下面是并行代码:

        static void Main(string[] args)
        {
            
            BigInteger currenthighest =new BigInteger(Math.Pow(2,68));
            BigInteger currentValue;
            Console.WriteLine(currenthighest);
            Console.ReadKey();
            for (int i = 1; i > -1; i++)
            {
               
                Parallel.For(0, 1000000,z=>
                 {
                     currentValue = currenthighest;
                     while (currentValue != 4)
                     {
                         if (currentValue % 2 == 0)
                         {
                             currentValue = currentValue / 2;
                         }
                         else
                         {
                             currentValue = (currentValue * 3) + 1;
                         }
                     }
                     currenthighest++;
                 });   
                Console.WriteLine(" {0} times done", i * 1000000);
            } 
        }

谁能帮我让它比普通的 for 循环更快,或者在这种情况下使用并行是愚蠢的,我应该只使用普通的 for 循环?如果我也将感谢任何帮助使正常的 for 循环更快。

Theodor Zoulias 指出性能不足的原因可能是因为它不是线程安全的。这可能会导致数字取任意值,并可能导致执行完全不同的计算。

要解决此问题,您需要使每个并行循环独立。据我所知,在您的示例中这很容易做到,因为您只需要确保所有修改的值都是本地的:

 static void Main(string[] args)
 {
        
        BigInteger startvalue =new BigInteger(Math.Pow(2,68));
        Console.WriteLine(startvalue );
        Console.ReadKey();
        for (int i = 1; i > -1; i++)
        {
            Parallel.For(0, 1000000,z=>
             {
                 var currentValue = startvalue + z;
                 while (currentValue != 4)
                 {
                     if (currentValue % 2 == 0)
                     {
                         currentValue = currentValue / 2;
                     }
                     else
                     {
                         currentValue = (currentValue * 3) + 1;
                     }
                 }
             });   
            Console.WriteLine(" {0} times done", i * 1000000);
       }
    }

另一种可能是并行循环内的工作平均来说很小,导致线程开销很大。还有工作平衡的问题,Parallel.For 会在 'chunks' 做工作以减少线程开销,并尝试调整这些块的大小。如果工作量变化很大,这种适应可能会导致效率低下。