如何将for循环修改为Parallel.For? C#

时间:2019-04-12 09:37:22

标签: c# parallel-processing parallel.for

我创建了一个非常简单的应用来计算素数,然后编写它们。如果用户选择计算1 000 000 ...

,我想让它在所有内核上运行

如何将已经运行的周期转换为在所有内核上运行? 我发现有一个Parallel.For,但我真的不知道如何从我现有的周期中转换为那个...

    {
        bool isPrime = true;
        int fPrime = Convert.ToInt32(txt_input.Text);
        Application.DoEvents();

        for (int i = 2; i <= fPrime; i++)
        {
            for (int j = 2; j <= fPrime; j++)
            {

                if (i != j && i % j == 0)
                {
                    isPrime = false;
                    break;
                }

            }

            if (isPrime)
            {
                txt_result.Text = txt_result.Text + "..." + i;
            }
            isPrime = true;
        }

        txt_result.Text = txt_result.Text + Environment.NewLine + "Done";
    }

3 个答案:

答案 0 :(得分:1)

更好的算法通常胜过(但并行化)一种:

private static IEnumerable<int> Primes(int upTo) {
  if (upTo <= 1)
    yield break;

  yield return 2; // Special case: the only even prime

  List<int> primes = new List<int>() { };

  for (int number = 3; number <= upTo; number += 2) {
    int max = (int)(Math.Sqrt(number) + 0.5);
    bool isPrime = true;

    foreach (var div in primes)
      if (div > max)
        break;
      else if (number % div == 0) {
        isPrime = false;

        break;
      }

    if (isPrime) {
      primes.Add(number);

      yield return number;
    }
  }
}

...

txt_result.Text = string.Join(", ", Primes(1000000));

您将拥有

2, 3, 5, 7, 11, 13, 17, 19, 23, ... 999959, 999961, 999979, 999983

几分之一秒

答案 1 :(得分:1)

您将无法使用并行foreach更新UI,可以编写一种方法来返回所有素数

        private static List<int> PrimeNumbers(int input)
        {
            var bag = new ConcurrentBag<int>();
            Parallel.ForEach(Enumerable.Range(2, input), x =>
            {
                var isPrime = true;
                Parallel.ForEach(Enumerable.Range(2, input), (y, state) =>
                {
                    if ((x != y) && (x % y) == 0)
                    {
                        isPrime = false;
                        state.Break();
                    }
                });
                if (isPrime)
                    bag.Add(x);
            });

            return bag.AsEnumerable().OrderBy(x => x).ToList();
        }

答案 2 :(得分:0)

并行化外循环应该足够了。您可能不会在具有比外循环更多的处理器的机器上运行程序!

Parallel.For(fromInclusive: 2, toExclusive: fPrime + 1, i =>
{
    for (int j = 2; j <= fPrime; j++)
    {

        if (i != j && i % j == 0)
        {
            isPrime = false;
            break;
        }

    }

    if (isPrime)
    {
        if (txt_result.InvokeRequired)
        {
            txt_result.Invoke((MethodInvoker)delegate { txt_result.Text = txt_result.Text + "..." + i; });
        }
        else
        {
            txt_result.Text = txt_result.Text + "..." + i;
        }
    }
    isPrime = true;
});
txt_result.Text = txt_result.Text + Environment.NewLine + "Done";