gpt4 book ai didi

c# - Parallel.ForEach 比正常的 foreach 慢

转载 作者:行者123 更新时间:2023-11-30 19:24:10 29 4
gpt4 key购买 nike

我正在 C# 控制台应用程序中使用 Parallel.ForEach,但似乎无法正确处理。我正在创建一个包含随机数的数组,我有一个顺序的 foreach 和一个 Parallel.ForEach,它可以找到数组中的最大值。使用 C++ 中大致相同的代码,我开始看到在数组中使用 3M 值的多个线程的权衡。但是 Parallel.ForEach 即使在 100M 值时也慢两倍。我做错了什么?

class Program
{
static void Main(string[] args)
{
dostuff();

}

static void dostuff() {
Console.WriteLine("How large do you want the array to be?");
int size = int.Parse(Console.ReadLine());

int[] arr = new int[size];
Random rand = new Random();
for (int i = 0; i < size; i++)
{
arr[i] = rand.Next(0, int.MaxValue);
}

var watchSeq = System.Diagnostics.Stopwatch.StartNew();
var largestSeq = FindLargestSequentially(arr);
watchSeq.Stop();
var elapsedSeq = watchSeq.ElapsedMilliseconds;
Console.WriteLine("Finished sequential in: " + elapsedSeq + "ms. Largest = " + largestSeq);

var watchPar = System.Diagnostics.Stopwatch.StartNew();
var largestPar = FindLargestParallel(arr);
watchPar.Stop();
var elapsedPar = watchPar.ElapsedMilliseconds;
Console.WriteLine("Finished parallel in: " + elapsedPar + "ms Largest = " + largestPar);

dostuff();
}

static int FindLargestSequentially(int[] arr) {
int largest = arr[0];
foreach (int i in arr) {
if (largest < i) {
largest = i;
}
}
return largest;
}

static int FindLargestParallel(int[] arr) {
int largest = arr[0];
Parallel.ForEach<int, int>(arr, () => 0, (i, loop, subtotal) =>
{
if (i > subtotal)
subtotal = i;
return subtotal;
},
(finalResult) => {
Console.WriteLine("Thread finished with result: " + finalResult);
if (largest < finalResult) largest = finalResult;
}
);
return largest;
}
}

最佳答案

这是拥有一个非常小的代表机构的性能后果。

我们可以使用分区实现更好的性能。在这种情况下,正文代表执行具有高数据量的工作。

static int FindLargestParallelRange(int[] arr)
{
object locker = new object();
int largest = arr[0];
Parallel.ForEach(Partitioner.Create(0, arr.Length), () => arr[0], (range, loop, subtotal) =>
{
for (int i = range.Item1; i < range.Item2; i++)
if (arr[i] > subtotal)
subtotal = arr[i];
return subtotal;
},
(finalResult) =>
{
lock (locker)
if (largest < finalResult)
largest = finalResult;
});
return largest;
}

注意同步localFinally委托(delegate)。还要注意需要正确初始化 localInit:() => arr[0] 而不是 () => 0

使用 PLINQ 分区:

static int FindLargestPlinqRange(int[] arr)
{
return Partitioner.Create(0, arr.Length)
.AsParallel()
.Select(range =>
{
int largest = arr[0];
for (int i = range.Item1; i < range.Item2; i++)
if (arr[i] > largest)
largest = arr[i];
return largest;
})
.Max();
}

我强烈推荐免费书籍 Patterns of Parallel Programming Stephen Toub 着。

关于c# - Parallel.ForEach 比正常的 foreach 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39540106/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com