我创建了一个非常简单的应用来计算素数,然后编写它们。如果用户选择计算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";
}
答案 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";